diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index d8aeb0c..e168ba2 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -370,7 +370,7 @@
 }
 
 status_t DrmManager::getAllSupportInfo(
-                    int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
+                    int /* uniqueId */, int* length, DrmSupportInfo** drmSupportInfoArray) {
     Mutex::Autolock _l(mLock);
     Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
     int size = plugInPathList.size();
diff --git a/drm/drmserver/main_drmserver.cpp b/drm/drmserver/main_drmserver.cpp
index 434d561..1ce42e8 100644
--- a/drm/drmserver/main_drmserver.cpp
+++ b/drm/drmserver/main_drmserver.cpp
@@ -26,7 +26,7 @@
 
 using namespace android;
 
-int main(int argc, char** argv)
+int main()
 {
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm = defaultServiceManager();
diff --git a/drm/libdrmframework/Android.mk b/drm/libdrmframework/Android.mk
index 33f9d3b..cafcb94 100644
--- a/drm/libdrmframework/Android.mk
+++ b/drm/libdrmframework/Android.mk
@@ -38,6 +38,7 @@
     $(TOP)/frameworks/av/drm/libdrmframework/include \
     $(TOP)/frameworks/av/include
 
+LOCAL_CFLAGS += -Werror
 
 
 LOCAL_MODULE_TAGS := optional
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index 9457bb6..cbd013e 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -350,7 +350,8 @@
     }
 }
 
-void DrmManagerClientImpl::DeathNotifier::binderDied(const wp<IBinder>& who) {
+void DrmManagerClientImpl::DeathNotifier::binderDied(
+            const wp<IBinder>& /* who */) {
     Mutex::Autolock lock(sMutex);
     DrmManagerClientImpl::sDrmManagerService.clear();
     ALOGW("DrmManager server died!");
diff --git a/drm/libdrmframework/NoOpDrmManagerClientImpl.cpp b/drm/libdrmframework/NoOpDrmManagerClientImpl.cpp
index dab583d..1172e80 100644
--- a/drm/libdrmframework/NoOpDrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/NoOpDrmManagerClientImpl.cpp
@@ -18,134 +18,209 @@
 
 namespace android {
 
-void NoOpDrmManagerClientImpl::remove(int uniqueId) {
+void NoOpDrmManagerClientImpl::remove(int /* uniqueId */) {
 }
 
-void NoOpDrmManagerClientImpl::addClient(int uniqueId) {
+void NoOpDrmManagerClientImpl::addClient(int /* uniqueId */) {
 }
 
-void NoOpDrmManagerClientImpl::removeClient(int uniqueId) {
+void NoOpDrmManagerClientImpl::removeClient(
+            int /* uniqueId */) {
 }
 
 status_t NoOpDrmManagerClientImpl::setOnInfoListener(
-            int uniqueId, const sp<DrmManagerClient::OnInfoListener>& infoListener) {
+            int /* uniqueId */,
+            const sp<DrmManagerClient::OnInfoListener>& /* infoListener */) {
     return UNKNOWN_ERROR;
 }
 
-DrmConstraints* NoOpDrmManagerClientImpl::getConstraints(int uniqueId, const String8* path, const int action) {
+DrmConstraints* NoOpDrmManagerClientImpl::getConstraints(
+            int /* uniqueId */,
+            const String8* /* path */,
+            const int /* action */) {
     return NULL;
 }
 
-DrmMetadata* NoOpDrmManagerClientImpl::getMetadata(int uniqueId, const String8* path) {
+DrmMetadata* NoOpDrmManagerClientImpl::getMetadata(
+            int /* uniqueId */,
+            const String8* /* path */) {
     return NULL;
 }
 
-bool NoOpDrmManagerClientImpl::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+bool NoOpDrmManagerClientImpl::canHandle(
+            int /* uniqueId */,
+            const String8& /* path */,
+            const String8& /* mimeType */) {
     return false;
 }
 
-DrmInfoStatus* NoOpDrmManagerClientImpl::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+DrmInfoStatus* NoOpDrmManagerClientImpl::processDrmInfo(
+            int /* uniqueId */,
+            const DrmInfo* /* drmInfo */) {
     return NULL;
 }
 
-DrmInfo* NoOpDrmManagerClientImpl::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+DrmInfo* NoOpDrmManagerClientImpl::acquireDrmInfo(
+            int /* uniqueId */,
+            const DrmInfoRequest* /* drmInfoRequest */) {
     return NULL;
 }
 
-status_t NoOpDrmManagerClientImpl::saveRights(int uniqueId, const DrmRights& drmRights,
-            const String8& rightsPath, const String8& contentPath) {
+status_t NoOpDrmManagerClientImpl::saveRights(
+            int /* uniqueId */,
+            const DrmRights& /* drmRights */,
+            const String8& /* rightsPath */,
+            const String8& /* contentPath */) {
     return UNKNOWN_ERROR;
 }
 
-String8 NoOpDrmManagerClientImpl::getOriginalMimeType(int uniqueId, const String8& path, int fd) {
+String8 NoOpDrmManagerClientImpl::getOriginalMimeType(
+            int /* uniqueId */,
+            const String8& /* path */,
+            int /* fd */) {
     return String8();
 }
 
-int NoOpDrmManagerClientImpl::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
+int NoOpDrmManagerClientImpl::getDrmObjectType(
+            int /* uniqueId */,
+            const String8& /* path */,
+            const String8& /* mimeType */) {
     return -1;
 }
 
-int NoOpDrmManagerClientImpl::checkRightsStatus(int uniqueId, const String8& path, int action) {
+int NoOpDrmManagerClientImpl::checkRightsStatus(
+            int /* uniqueId */,
+            const String8& /* path */,
+            int /* action */) {
     return -1;
 }
 
-status_t NoOpDrmManagerClientImpl::consumeRights(int uniqueId, sp<DecryptHandle> &decryptHandle, int action, bool reserve) {
+status_t NoOpDrmManagerClientImpl::consumeRights(
+            int /* uniqueId */,
+            sp<DecryptHandle> &/* decryptHandle */,
+            int /* action */,
+            bool /* reserve */) {
     return UNKNOWN_ERROR;
 }
 
 status_t NoOpDrmManagerClientImpl::setPlaybackStatus(
-            int uniqueId, sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position) {
+            int /* uniqueId */,
+            sp<DecryptHandle> &/* decryptHandle */,
+            int /* playbackStatus */,
+            int64_t /* position */) {
     return UNKNOWN_ERROR;
 }
 
 bool NoOpDrmManagerClientImpl::validateAction(
-        int uniqueId, const String8& path, int action, const ActionDescription& description) {
+            int /* uniqueId */,
+            const String8& /* path */,
+            int /* action */,
+            const ActionDescription& /* description */) {
     return false;
 }
 
-status_t NoOpDrmManagerClientImpl::removeRights(int uniqueId, const String8& path) {
+status_t NoOpDrmManagerClientImpl::removeRights(
+            int /* uniqueId */,
+            const String8& /* path */) {
     return UNKNOWN_ERROR;
 }
 
-status_t NoOpDrmManagerClientImpl::removeAllRights(int uniqueId) {
+status_t NoOpDrmManagerClientImpl::removeAllRights(
+            int /* uniqueId */) {
     return UNKNOWN_ERROR;
 }
 
-int NoOpDrmManagerClientImpl::openConvertSession(int uniqueId, const String8& mimeType) {
+int NoOpDrmManagerClientImpl::openConvertSession(
+            int /* uniqueId */,
+            const String8& /* mimeType */) {
     return -1;
 }
 
-DrmConvertedStatus* NoOpDrmManagerClientImpl::convertData(int uniqueId, int convertId, const DrmBuffer* inputData) {
+DrmConvertedStatus* NoOpDrmManagerClientImpl::convertData(
+            int /* uniqueId */,
+            int /* convertId */,
+            const DrmBuffer* /* inputData */) {
     return NULL;
 }
 
-DrmConvertedStatus* NoOpDrmManagerClientImpl::closeConvertSession(int uniqueId, int convertId) {
+DrmConvertedStatus* NoOpDrmManagerClientImpl::closeConvertSession(
+            int /* uniqueId */,
+            int /* convertId */) {
     return NULL;
 }
 
-status_t NoOpDrmManagerClientImpl::getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
+status_t NoOpDrmManagerClientImpl::getAllSupportInfo(
+            int /* uniqueId */,
+            int* /* length */,
+            DrmSupportInfo** /* drmSupportInfoArray */) {
     return UNKNOWN_ERROR;
 }
 
 sp<DecryptHandle> NoOpDrmManagerClientImpl::openDecryptSession(
-            int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
+            int /* uniqueId */,
+            int /* fd */,
+            off64_t /* offset */,
+            off64_t /* length */,
+            const char* /* mime */) {
     return NULL;
 }
 
 sp<DecryptHandle> NoOpDrmManagerClientImpl::openDecryptSession(
-            int uniqueId, const char* uri, const char* mime) {
+            int /* uniqueId */,
+            const char* /* uri */,
+            const char* /* mime */) {
     return NULL;
 }
 
-sp<DecryptHandle> NoOpDrmManagerClientImpl::openDecryptSession(int uniqueId, const DrmBuffer& buf,
-            const String8& mimeType) {
+sp<DecryptHandle> NoOpDrmManagerClientImpl::openDecryptSession(
+            int /* uniqueId */,
+            const DrmBuffer& /* buf */,
+            const String8& /* mimeType */) {
     return NULL;
 }
 
-status_t NoOpDrmManagerClientImpl::closeDecryptSession(int uniqueId, sp<DecryptHandle> &decryptHandle) {
+status_t NoOpDrmManagerClientImpl::closeDecryptSession(
+            int /* uniqueId */,
+            sp<DecryptHandle> &/* decryptHandle */) {
     return UNKNOWN_ERROR;
 }
 
-status_t NoOpDrmManagerClientImpl::initializeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle,
-            int decryptUnitId, const DrmBuffer* headerInfo) {
+status_t NoOpDrmManagerClientImpl::initializeDecryptUnit(
+            int /* uniqueId */,
+            sp<DecryptHandle> &/* decryptHandle */,
+            int /* decryptUnitId */,
+            const DrmBuffer* /* headerInfo */) {
     return UNKNOWN_ERROR;
 }
 
-status_t NoOpDrmManagerClientImpl::decrypt(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId,
-            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+status_t NoOpDrmManagerClientImpl::decrypt(
+            int /* uniqueId */,
+            sp<DecryptHandle> &/* decryptHandle */,
+            int /* decryptUnitId */,
+            const DrmBuffer* /* encBuffer */,
+            DrmBuffer** /* decBuffer */,
+            DrmBuffer* /* IV */) {
     return UNKNOWN_ERROR;
 }
 
-status_t NoOpDrmManagerClientImpl::finalizeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId) {
+status_t NoOpDrmManagerClientImpl::finalizeDecryptUnit(
+            int /* uniqueId */,
+            sp<DecryptHandle> &/* decryptHandle */,
+            int /* decryptUnitId */) {
     return UNKNOWN_ERROR;
 }
 
-ssize_t NoOpDrmManagerClientImpl::pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
-            void* buffer, ssize_t numBytes, off64_t offset) {
+ssize_t NoOpDrmManagerClientImpl::pread(
+            int /* uniqueId */,
+            sp<DecryptHandle> &/* decryptHandle */,
+            void* /* buffer */,
+            ssize_t /* numBytes */,
+            off64_t /* offset */) {
     return -1;
 }
 
-status_t NoOpDrmManagerClientImpl::notify(const DrmInfoEvent& event) {
+status_t NoOpDrmManagerClientImpl::notify(
+            const DrmInfoEvent& /* event */) {
     return UNKNOWN_ERROR;
 }
 
diff --git a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
index fa51c13..417107f 100644
--- a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
+++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
@@ -398,9 +398,9 @@
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
     virtual status_t onOpenDecryptSession(
-            int uniqueId, DecryptHandle* decryptHandle,
-            int fd, off64_t offset, off64_t length,
-            const char* mime) {
+            int /* uniqueId */, DecryptHandle* /* decryptHandle */,
+            int /* fd */, off64_t /* offset */, off64_t /* length */,
+            const char* /* mime */) {
 
         return DRM_ERROR_CANNOT_HANDLE;
     }
@@ -430,8 +430,8 @@
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
     virtual status_t onOpenDecryptSession(
-            int uniqueId, DecryptHandle* decryptHandle,
-            const char* uri, const char* mime) {
+            int /* uniqueId */, DecryptHandle* /* decryptHandle */,
+            const char* /* uri */, const char* /* mime */) {
 
         return DRM_ERROR_CANNOT_HANDLE;
     }
@@ -446,8 +446,10 @@
      * @return
      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
      */
-    virtual status_t onOpenDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
-            const DrmBuffer& buf, const String8& mimeType) {
+    virtual status_t onOpenDecryptSession(int /* uniqueId */,
+            DecryptHandle* /* decryptHandle */,
+            const DrmBuffer& /* buf */,
+            const String8& /* mimeType */) {
         return DRM_ERROR_CANNOT_HANDLE;
     }
 
diff --git a/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
index 576ed15..4bd1adb 100644
--- a/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
+++ b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
@@ -115,7 +115,7 @@
  * replacement mimetype otherwise the original mimetype
  * is returned.
  *
- * If the mimetype is of unsupported group i.e. application/*
+ * If the mimetype is of unsupported group i.e. application / *
  * then "unsupported/drm.mimetype" will be returned.
  *
  * @param mimeType - mimetype in lower case to convert.
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
index f400732..a495616 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
@@ -119,7 +119,7 @@
     return drmConstraints;
 }
 
-DrmMetadata* FwdLockEngine::onGetMetadata(int uniqueId, const String8* path) {
+DrmMetadata* FwdLockEngine::onGetMetadata(int /* uniqueId */, const String8* path) {
     DrmMetadata* drmMetadata = NULL;
 
     LOG_VERBOSE("FwdLockEngine::onGetMetadata");
@@ -132,7 +132,7 @@
     return drmMetadata;
 }
 
-android::status_t FwdLockEngine::onInitialize(int uniqueId) {
+android::status_t FwdLockEngine::onInitialize(int /* uniqueId */) {
     LOG_VERBOSE("FwdLockEngine::onInitialize");
 
     if (FwdLockGlue_InitializeKeyEncryption()) {
@@ -146,14 +146,16 @@
 }
 
 android::status_t
-FwdLockEngine::onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
+FwdLockEngine::onSetOnInfoListener(
+            int /* uniqueId */,
+            const IDrmEngine::OnInfoListener* /* infoListener */) {
     // Not used
     LOG_VERBOSE("FwdLockEngine::onSetOnInfoListener");
 
     return DRM_NO_ERROR;
 }
 
-android::status_t FwdLockEngine::onTerminate(int uniqueId) {
+android::status_t FwdLockEngine::onTerminate(int /* uniqueId */) {
     LOG_VERBOSE("FwdLockEngine::onTerminate");
 
     return DRM_NO_ERROR;
@@ -207,7 +209,7 @@
     return false;
 }
 
-DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) {
+DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int /* uniqueId */) {
     DrmSupportInfo* pSupportInfo = new DrmSupportInfo();
 
     LOG_VERBOSE("FwdLockEngine::onGetSupportInfo");
@@ -222,14 +224,14 @@
     return pSupportInfo;
 }
 
-bool FwdLockEngine::onCanHandle(int uniqueId, const String8& path) {
+bool FwdLockEngine::onCanHandle(int /* uniqueId */, const String8& path) {
     bool result = false;
 
     String8 extString = path.getPathExtension();
     return IsFileSuffixSupported(extString);
 }
 
-DrmInfoStatus* FwdLockEngine::onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+DrmInfoStatus* FwdLockEngine::onProcessDrmInfo(int /* uniqueId */, const DrmInfo* /* drmInfo */) {
     DrmInfoStatus *drmInfoStatus = NULL;
 
     // Nothing to process
@@ -242,16 +244,17 @@
 }
 
 status_t FwdLockEngine::onSaveRights(
-            int uniqueId,
-            const DrmRights& drmRights,
-            const String8& rightsPath,
-            const String8& contentPath) {
+            int /* uniqueId */,
+            const DrmRights& /* drmRights */,
+            const String8& /* rightsPath */,
+            const String8& /* contentPath */) {
     // No rights to save. Return
     LOG_VERBOSE("FwdLockEngine::onSaveRights");
     return DRM_ERROR_UNKNOWN;
 }
 
-DrmInfo* FwdLockEngine::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+DrmInfo* FwdLockEngine::onAcquireDrmInfo(
+            int /* uniqueId */, const DrmInfoRequest* /* drmInfoRequest */) {
     DrmInfo* drmInfo = NULL;
 
     // Nothing to be done for Forward Lock file
@@ -290,10 +293,10 @@
     return result;
 }
 
-status_t FwdLockEngine::onConsumeRights(int uniqueId,
-                                        DecryptHandle* decryptHandle,
-                                        int action,
-                                        bool reserve) {
+status_t FwdLockEngine::onConsumeRights(int /* uniqueId */,
+                                        DecryptHandle* /* decryptHandle */,
+                                        int /* action */,
+                                        bool /* reserve */) {
     // No rights consumption
     LOG_VERBOSE("FwdLockEngine::onConsumeRights");
     return DRM_NO_ERROR;
@@ -302,14 +305,16 @@
 bool FwdLockEngine::onValidateAction(int uniqueId,
                                      const String8& path,
                                      int action,
-                                     const ActionDescription& description) {
+                                     const ActionDescription& /* description */) {
     LOG_VERBOSE("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, int fd) {
+String8 FwdLockEngine::onGetOriginalMimeType(int /* uniqueId */,
+                                             const String8& /* path */,
+                                             int fd) {
     LOG_VERBOSE("FwdLockEngine::onGetOriginalMimeType");
     String8 mimeString = String8("");
     int fileDesc = dup(fd);
@@ -354,32 +359,32 @@
     return DrmObjectType::UNKNOWN;
 }
 
-status_t FwdLockEngine::onRemoveRights(int uniqueId, const String8& path) {
+status_t FwdLockEngine::onRemoveRights(int /* uniqueId */, const String8& /* path */) {
     // No Rights to remove
     LOG_VERBOSE("FwdLockEngine::onRemoveRights");
     return DRM_NO_ERROR;
 }
 
-status_t FwdLockEngine::onRemoveAllRights(int uniqueId) {
+status_t FwdLockEngine::onRemoveAllRights(int /* uniqueId */) {
     // No rights to remove
     LOG_VERBOSE("FwdLockEngine::onRemoveAllRights");
     return DRM_NO_ERROR;
 }
 
 #ifdef USE_64BIT_DRM_API
-status_t FwdLockEngine::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
-                                            int playbackStatus, int64_t position) {
+status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */, DecryptHandle* /* decryptHandle */,
+                                            int /* playbackStatus */, int64_t /* position */) {
 #else
-status_t FwdLockEngine::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
-                                            int playbackStatus, int position) {
+status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */, DecryptHandle* /* decryptHandle */,
+                                            int /* playbackStatus */, int /* position */) {
 #endif
     // Not used
     LOG_VERBOSE("FwdLockEngine::onSetPlaybackStatus");
     return DRM_NO_ERROR;
 }
 
-status_t FwdLockEngine::onOpenConvertSession(int uniqueId,
-                                         int convertId) {
+status_t FwdLockEngine::onOpenConvertSession(
+            int /* uniqueId */, int convertId) {
     status_t result = DRM_ERROR_UNKNOWN;
     LOG_VERBOSE("FwdLockEngine::onOpenConvertSession");
     if (!convertSessionMap.isCreated(convertId)) {
@@ -396,7 +401,7 @@
     return result;
 }
 
-DrmConvertedStatus* FwdLockEngine::onConvertData(int uniqueId,
+DrmConvertedStatus* FwdLockEngine::onConvertData(int /* uniqueId */,
                                                  int convertId,
                                                  const DrmBuffer* inputData) {
     FwdLockConv_Status_t retStatus = FwdLockConv_Status_InvalidArgument;
@@ -432,7 +437,7 @@
     return new DrmConvertedStatus(getConvertedStatus(retStatus), convResult, offset);
 }
 
-DrmConvertedStatus* FwdLockEngine::onCloseConvertSession(int uniqueId,
+DrmConvertedStatus* FwdLockEngine::onCloseConvertSession(int /* uniqueId */,
                                                          int convertId) {
     FwdLockConv_Status_t retStatus = FwdLockConv_Status_InvalidArgument;
     DrmBuffer *convResult = new DrmBuffer(NULL, 0);
@@ -464,17 +469,17 @@
 }
 
 #ifdef USE_64BIT_DRM_API
-status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
+status_t FwdLockEngine::onOpenDecryptSession(int /* uniqueId */,
                                              DecryptHandle* decryptHandle,
                                              int fd,
                                              off64_t offset,
-                                             off64_t length) {
+                                             off64_t /* length */) {
 #else
-status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
+status_t FwdLockEngine::onOpenDecryptSession(int /* uniqueId */,
                                              DecryptHandle* decryptHandle,
                                              int fd,
                                              int offset,
-                                             int length) {
+                                             int /* length */) {
 #endif
     status_t result = DRM_ERROR_CANNOT_HANDLE;
     int fileDesc = -1;
@@ -552,7 +557,7 @@
     return result;
 }
 
-status_t FwdLockEngine::onCloseDecryptSession(int uniqueId,
+status_t FwdLockEngine::onCloseDecryptSession(int /* uniqueId */,
                                               DecryptHandle* decryptHandle) {
     status_t result = DRM_ERROR_UNKNOWN;
     LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession");
@@ -584,37 +589,42 @@
     return result;
 }
 
-status_t FwdLockEngine::onInitializeDecryptUnit(int uniqueId,
-                                                DecryptHandle* decryptHandle,
-                                                int decryptUnitId,
-                                                const DrmBuffer* headerInfo) {
+status_t FwdLockEngine::onInitializeDecryptUnit(int /* uniqueId */,
+                                                DecryptHandle* /* decryptHandle */,
+                                                int /* decryptUnitId */,
+                                                const DrmBuffer* /* headerInfo */) {
     ALOGE("FwdLockEngine::onInitializeDecryptUnit is not supported for this DRM scheme");
     return DRM_ERROR_UNKNOWN;
 }
 
-status_t FwdLockEngine::onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
-            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+status_t FwdLockEngine::onDecrypt(
+            int /* uniqueId */,
+            DecryptHandle* /* decryptHandle */,
+            int /* decryptUnitId */,
+            const DrmBuffer* /* encBuffer */,
+            DrmBuffer** /* decBuffer */,
+            DrmBuffer* /* IV */) {
     ALOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
     return DRM_ERROR_UNKNOWN;
 }
 
-status_t FwdLockEngine::onDecrypt(int uniqueId,
-                                  DecryptHandle* decryptHandle,
-                                  int decryptUnitId,
-                                  const DrmBuffer* encBuffer,
-                                  DrmBuffer** decBuffer) {
+status_t FwdLockEngine::onDecrypt(int /* uniqueId */,
+                                  DecryptHandle* /* decryptHandle */,
+                                  int /* decryptUnitId */,
+                                  const DrmBuffer* /* encBuffer */,
+                                  DrmBuffer** /* decBuffer */) {
     ALOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
     return DRM_ERROR_UNKNOWN;
 }
 
-status_t FwdLockEngine::onFinalizeDecryptUnit(int uniqueId,
-                                              DecryptHandle* decryptHandle,
-                                              int decryptUnitId) {
+status_t FwdLockEngine::onFinalizeDecryptUnit(int /* uniqueId */,
+                                              DecryptHandle* /* decryptHandle */,
+                                              int /* decryptUnitId */) {
     ALOGE("FwdLockEngine::onFinalizeDecryptUnit is not supported for this DRM scheme");
     return DRM_ERROR_UNKNOWN;
 }
 
-ssize_t FwdLockEngine::onRead(int uniqueId,
+ssize_t FwdLockEngine::onRead(int /* uniqueId */,
                               DecryptHandle* decryptHandle,
                               void* buffer,
                               int numBytes) {
@@ -640,10 +650,10 @@
 }
 
 #ifdef USE_64BIT_DRM_API
-off64_t FwdLockEngine::onLseek(int uniqueId, DecryptHandle* decryptHandle,
+off64_t FwdLockEngine::onLseek(int /* uniqueId */, DecryptHandle* decryptHandle,
                                off64_t offset, int whence) {
 #else
-off_t FwdLockEngine::onLseek(int uniqueId, DecryptHandle* decryptHandle,
+off_t FwdLockEngine::onLseek(int /* uniqueId */, DecryptHandle* decryptHandle,
                              off_t offset, int whence) {
 #endif
     off_t offval = -1;
diff --git a/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
index 6666343..ee97976 100644
--- a/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
@@ -33,7 +33,7 @@
 // decrypted data.  In theory, the output size can be larger than the input
 // size, but in practice this will never happen for AES-CTR.
 ssize_t CryptoPlugin::decrypt(bool secure, const KeyId keyId, const Iv iv,
-                              Mode mode, const Pattern &pattern, const void* srcPtr,
+                              Mode mode, const Pattern &/* pattern */, const void* srcPtr,
                               const SubSample* subSamples, size_t numSubSamples,
                               void* dstPtr, AString* errorDetailMsg) {
     if (secure) {
diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h
index 5e324ad..a4bfaf8 100644
--- a/include/media/ICrypto.h
+++ b/include/media/ICrypto.h
@@ -46,8 +46,14 @@
 
     virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0;
 
+    enum DestinationType {
+        kDestinationTypeVmPointer,    // non-secure
+        kDestinationTypeOpaqueHandle, // secure
+        kDestinationTypeNativeHandle  // secure
+    };
+
     virtual ssize_t decrypt(
-            bool secure,
+            DestinationType dstType,
             const uint8_t key[16],
             const uint8_t iv[16],
             CryptoPlugin::Mode mode,
diff --git a/include/media/IMediaDrmService.h b/include/media/IMediaDrmService.h
new file mode 100644
index 0000000..323fae5
--- /dev/null
+++ b/include/media/IMediaDrmService.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 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_IMEDIADRMSERVICE_H
+#define ANDROID_IMEDIADRMSERVICE_H
+
+#include <utils/Errors.h>  // for status_t
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+struct ICrypto;
+struct IDrm;
+
+class IMediaDrmService: public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(MediaDrmService);
+
+    virtual sp<ICrypto>         makeCrypto() = 0;
+    virtual sp<IDrm>            makeDrm() = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaDrmService: public BnInterface<IMediaDrmService>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIADRMSERVICE_H
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 27ad694..d6db67a 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -98,8 +98,8 @@
             node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
             OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0;
 
-    virtual status_t enableGraphicBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
+    virtual status_t enableNativeBuffers(
+            node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) = 0;
 
     virtual status_t getGraphicBufferUsage(
             node_id node, OMX_U32 port_index, OMX_U32* usage) = 0;
@@ -137,13 +137,14 @@
 
     virtual status_t signalEndOfInputStream(node_id node) = 0;
 
-    // This API clearly only makes sense if the caller lives in the
-    // same process as the callee, i.e. is the media_server, as the
-    // returned "buffer_data" pointer is just that, a pointer into local
-    // address space.
-    virtual status_t allocateBuffer(
+    // Allocate an opaque buffer as a native handle. If component supports returning native
+    // handles, those are returned in *native_handle. Otherwise, the allocated buffer is
+    // returned in *buffer_data. This clearly only makes sense if the caller lives in the
+    // same process as the callee, i.e. is the media_server, as the returned "buffer_data"
+    // pointer is just that, a pointer into local address space.
+    virtual status_t allocateSecureBuffer(
             node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer, void **buffer_data) = 0;
+            buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) = 0;
 
     // Allocate an OMX buffer of size |allotedSize|. Use |params| as the backup buffer, which
     // may be larger.
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 349db64..cc5b486 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -26,6 +26,7 @@
 #include <media/stagefright/CodecBase.h>
 #include <media/stagefright/FrameRenderTracker.h>
 #include <media/stagefright/SkipCutBuffer.h>
+#include <utils/NativeHandle.h>
 #include <OMX_Audio.h>
 
 #define TRACK_BUFFER_TIMING     0
@@ -72,6 +73,7 @@
         size_t countBuffers();
         IOMX::buffer_id bufferIDAt(size_t index) const;
         sp<ABuffer> bufferAt(size_t index) const;
+        sp<NativeHandle> handleAt(size_t index) const;
         sp<RefBase> memRefAt(size_t index) const;
 
     private:
@@ -79,10 +81,13 @@
 
         Vector<IOMX::buffer_id> mBufferIDs;
         Vector<sp<ABuffer> > mBuffers;
+        Vector<sp<NativeHandle> > mHandles;
         Vector<sp<RefBase> > mMemRefs;
 
         PortDescription();
-        void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer, const sp<RefBase> &memRef);
+        void addBuffer(
+                IOMX::buffer_id id, const sp<ABuffer> &buffer,
+                const sp<NativeHandle> &handle, const sp<RefBase> &memRef);
 
         DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
     };
@@ -186,6 +191,7 @@
         sp<ABuffer> mData;
         sp<RefBase> mMemRef;
         sp<GraphicBuffer> mGraphicBuffer;
+        sp<NativeHandle> mNativeHandle;
         int mFenceFd;
         FrameRenderTracker::Info *mRenderInfo;
 
diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h
index 01b744b..cbf9839 100644
--- a/include/media/stagefright/CodecBase.h
+++ b/include/media/stagefright/CodecBase.h
@@ -23,6 +23,7 @@
 
 #include <media/MediaCodecInfo.h>
 #include <media/stagefright/foundation/AHandler.h>
+#include <utils/NativeHandle.h>
 
 namespace android {
 
@@ -77,6 +78,7 @@
         virtual size_t countBuffers() = 0;
         virtual IOMX::buffer_id bufferIDAt(size_t index) const = 0;
         virtual sp<ABuffer> bufferAt(size_t index) const = 0;
+        virtual sp<NativeHandle> handleAt(size_t index) { return NULL; };
         virtual sp<RefBase> memRefAt(size_t index) const { return NULL; }
 
     protected:
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index ea708e3..2bb1291 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -254,6 +254,7 @@
     struct BufferInfo {
         uint32_t mBufferID;
         sp<ABuffer> mData;
+        sp<NativeHandle> mNativeHandle;
         sp<RefBase> mMemRef;
         sp<ABuffer> mEncryptedData;
         sp<IMemory> mSharedEncryptedBuffer;
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index 78da861..1bd3ed0 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -59,8 +59,9 @@
             MediaBuffer **buffer, const ReadOptions *options = NULL) = 0;
 
     // Causes this source to suspend pulling data from its upstream source
-    // until a subsequent read-with-seek. Currently only supported by
-    // OMXCodec.
+    // until a subsequent read-with-seek. This is currently not supported
+    // as such by any source. E.g. MediaCodecSource does not suspend its
+    // upstream source, and instead discard upstream data while paused.
     virtual status_t pause() {
         return ERROR_UNSUPPORTED;
     }
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
deleted file mode 100644
index 5f2f3bf..0000000
--- a/include/media/stagefright/OMXCodec.h
+++ /dev/null
@@ -1,406 +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.
- */
-
-#ifndef OMX_CODEC_H_
-
-#define OMX_CODEC_H_
-
-#include <android/native_window.h>
-#include <media/IOMX.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaSource.h>
-#include <utils/threads.h>
-
-#include <OMX_Audio.h>
-
-namespace android {
-
-struct MediaCodecInfo;
-class MemoryDealer;
-struct OMXCodecObserver;
-struct CodecProfileLevel;
-class SkipCutBuffer;
-
-struct OMXCodec : public BnMediaSource,
-                  public MediaBufferObserver {
-    enum CreationFlags {
-        kPreferSoftwareCodecs    = 1,
-        kIgnoreCodecSpecificData = 2,
-
-        // The client wants to access the output buffer's video
-        // data for example for thumbnail extraction.
-        kClientNeedsFramebuffer  = 4,
-
-        // Request for software or hardware codecs. If request
-        // can not be fullfilled, Create() returns NULL.
-        kSoftwareCodecsOnly      = 8,
-        kHardwareCodecsOnly      = 16,
-
-        // Store meta data in video buffers
-        kStoreMetaDataInVideoBuffers = 32,
-
-        // Only submit one input buffer at one time.
-        kOnlySubmitOneInputBufferAtOneTime = 64,
-
-        // Enable GRALLOC_USAGE_PROTECTED for output buffers from native window
-        kEnableGrallocUsageProtected = 128,
-
-        // Secure decoding mode
-        kUseSecureInputBuffers = 256,
-    };
-    static sp<IMediaSource> Create(
-            const sp<IOMX> &omx,
-            const sp<MetaData> &meta, bool createEncoder,
-            const sp<IMediaSource> &source,
-            const char *matchComponentName = NULL,
-            uint32_t flags = 0,
-            const sp<ANativeWindow> &nativeWindow = NULL);
-
-    static void setComponentRole(
-            const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
-            const char *mime);
-
-    virtual status_t start(MetaData *params = NULL);
-    virtual status_t stop();
-
-    virtual sp<MetaData> getFormat();
-
-    virtual status_t read(
-            MediaBuffer **buffer, const ReadOptions *options = NULL);
-
-    virtual status_t pause();
-
-    // from MediaBufferObserver
-    virtual void signalBufferReturned(MediaBuffer *buffer);
-
-    enum Quirks {
-        kNeedsFlushBeforeDisable              = 1,
-        kWantsNALFragments                    = 2,
-        kRequiresLoadedToIdleAfterAllocation  = 4,
-        kRequiresAllocateBufferOnInputPorts   = 8,
-        kRequiresFlushCompleteEmulation       = 16,
-        kRequiresAllocateBufferOnOutputPorts  = 32,
-        kRequiresFlushBeforeShutdown          = 64,
-        kDefersOutputBufferAllocation         = 128,
-        kDecoderLiesAboutNumberOfChannels     = 256,
-        kInputBufferSizesAreBogus             = 512,
-        kSupportsMultipleFramesPerInputBuffer = 1024,
-        kRequiresLargerEncoderOutputBuffer    = 2048,
-        kOutputBuffersAreUnreadable           = 4096,
-    };
-
-    struct CodecNameAndQuirks {
-        String8 mName;
-        uint32_t mQuirks;
-    };
-
-    // for use by ACodec
-    static void findMatchingCodecs(
-            const char *mime,
-            bool createEncoder, const char *matchComponentName,
-            uint32_t flags,
-            Vector<CodecNameAndQuirks> *matchingCodecNamesAndQuirks);
-
-    static uint32_t getComponentQuirks(
-            const sp<MediaCodecInfo> &list);
-
-protected:
-    virtual ~OMXCodec();
-
-private:
-
-    // Make sure mLock is accessible to OMXCodecObserver
-    friend class OMXCodecObserver;
-
-    // Call this with mLock hold
-    void on_message(const omx_message &msg);
-
-    enum State {
-        DEAD,
-        LOADED,
-        LOADED_TO_IDLE,
-        IDLE_TO_EXECUTING,
-        EXECUTING,
-        EXECUTING_TO_IDLE,
-        IDLE_TO_LOADED,
-        RECONFIGURING,
-        ERROR
-    };
-
-    enum {
-        kPortIndexInput  = 0,
-        kPortIndexOutput = 1
-    };
-
-    enum PortStatus {
-        ENABLED,
-        DISABLING,
-        DISABLED,
-        ENABLING,
-        SHUTTING_DOWN,
-    };
-
-    enum BufferStatus {
-        OWNED_BY_US,
-        OWNED_BY_COMPONENT,
-        OWNED_BY_NATIVE_WINDOW,
-        OWNED_BY_CLIENT,
-    };
-
-    struct BufferInfo {
-        IOMX::buffer_id mBuffer;
-        BufferStatus mStatus;
-        sp<IMemory> mMem;
-        size_t mSize;
-        void *mData;
-        MediaBuffer *mMediaBuffer;
-    };
-
-    struct CodecSpecificData {
-        size_t mSize;
-        uint8_t mData[1];
-    };
-
-    sp<IOMX> mOMX;
-    bool mOMXLivesLocally;
-    IOMX::node_id mNode;
-    uint32_t mQuirks;
-
-    // Flags specified in the creation of the codec.
-    uint32_t mFlags;
-
-    bool mIsEncoder;
-    bool mIsVideo;
-    char *mMIME;
-    char *mComponentName;
-    sp<MetaData> mOutputFormat;
-    sp<IMediaSource> mSource;
-    Vector<CodecSpecificData *> mCodecSpecificData;
-    size_t mCodecSpecificDataIndex;
-
-    sp<MemoryDealer> mDealer[2];
-
-    State mState;
-    Vector<BufferInfo> mPortBuffers[2];
-    PortStatus mPortStatus[2];
-    bool mInitialBufferSubmit;
-    bool mSignalledEOS;
-    status_t mFinalStatus;
-    bool mNoMoreOutputData;
-    bool mOutputPortSettingsHaveChanged;
-    int64_t mSeekTimeUs;
-    ReadOptions::SeekMode mSeekMode;
-    int64_t mTargetTimeUs;
-    bool mOutputPortSettingsChangedPending;
-    sp<SkipCutBuffer> mSkipCutBuffer;
-
-    MediaBuffer *mLeftOverBuffer;
-
-    Mutex mLock;
-    Condition mAsyncCompletion;
-
-    bool mPaused;
-
-    sp<ANativeWindow> mNativeWindow;
-
-    // The index in each of the mPortBuffers arrays of the buffer that will be
-    // submitted to OMX next.  This only applies when using buffers from a
-    // native window.
-    size_t mNextNativeBufferIndex[2];
-
-    // A list of indices into mPortStatus[kPortIndexOutput] filled with data.
-    List<size_t> mFilledBuffers;
-    Condition mBufferFilled;
-
-    // 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, uint32_t flags,
-             bool isEncoder, const char *mime, const char *componentName,
-             const sp<IMediaSource> &source,
-             const sp<ANativeWindow> &nativeWindow);
-
-    void addCodecSpecificData(const void *data, size_t size);
-    void clearCodecSpecificData();
-
-    void setComponentRole();
-
-    void setAMRFormat(bool isWAMR, int32_t bitRate);
-
-    status_t setAACFormat(
-            int32_t numChannels, int32_t sampleRate, int32_t bitRate,
-            int32_t aacProfile, bool isADTS);
-
-    status_t setAC3Format(int32_t numChannels, int32_t sampleRate);
-
-    void setG711Format(int32_t sampleRate, int32_t numChannels);
-
-    status_t setVideoPortFormatType(
-            OMX_U32 portIndex,
-            OMX_VIDEO_CODINGTYPE compressionFormat,
-            OMX_COLOR_FORMATTYPE colorFormat);
-
-    void setVideoInputFormat(
-            const char *mime, const sp<MetaData>& meta);
-
-    status_t setupBitRate(int32_t bitRate);
-    status_t setupErrorCorrectionParameters();
-    status_t setupH263EncoderParameters(const sp<MetaData>& meta);
-    status_t setupMPEG4EncoderParameters(const sp<MetaData>& meta);
-    status_t setupAVCEncoderParameters(const sp<MetaData>& meta);
-    status_t findTargetColorFormat(
-            const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat);
-
-    status_t isColorFormatSupported(
-            OMX_COLOR_FORMATTYPE colorFormat, int portIndex);
-
-    // If profile/level is set in the meta data, its value in the meta
-    // data will be used; otherwise, the default value will be used.
-    status_t getVideoProfileLevel(const sp<MetaData>& meta,
-            const CodecProfileLevel& defaultProfileLevel,
-            CodecProfileLevel& profileLevel);
-
-    status_t setVideoOutputFormat(
-            const char *mime, const sp<MetaData>& meta);
-
-    void setImageOutputFormat(
-            OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height);
-
-    void setJPEGInputFormat(
-            OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize);
-
-    void setMinBufferSize(OMX_U32 portIndex, OMX_U32 size);
-
-    void setRawAudioFormat(
-            OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
-
-    status_t allocateBuffers();
-    status_t allocateBuffersOnPort(OMX_U32 portIndex);
-    status_t allocateOutputBuffersFromNativeWindow();
-
-    status_t queueBufferToNativeWindow(BufferInfo *info);
-    status_t cancelBufferToNativeWindow(BufferInfo *info);
-    BufferInfo* dequeueBufferFromNativeWindow();
-
-    status_t freeBuffersOnPort(
-            OMX_U32 portIndex, bool onlyThoseWeOwn = false);
-
-    status_t freeBuffer(OMX_U32 portIndex, size_t bufIndex);
-
-    bool drainInputBuffer(IOMX::buffer_id buffer);
-    void fillOutputBuffer(IOMX::buffer_id buffer);
-    bool drainInputBuffer(BufferInfo *info);
-    void fillOutputBuffer(BufferInfo *info);
-
-    void drainInputBuffers();
-    void fillOutputBuffers();
-
-    bool drainAnyInputBuffer();
-    BufferInfo *findInputBufferByDataPointer(void *ptr);
-    BufferInfo *findEmptyInputBuffer();
-
-    // Returns true iff a flush was initiated and a completion event is
-    // upcoming, false otherwise (A flush was not necessary as we own all
-    // the buffers on that port).
-    // This method will ONLY ever return false for a component with quirk
-    // "kRequiresFlushCompleteEmulation".
-    bool flushPortAsync(OMX_U32 portIndex);
-
-    void disablePortAsync(OMX_U32 portIndex);
-    status_t enablePortAsync(OMX_U32 portIndex);
-
-    static size_t countBuffersWeOwn(const Vector<BufferInfo> &buffers);
-    static bool isIntermediateState(State state);
-
-    void onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
-    void onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data);
-    void onStateChange(OMX_STATETYPE newState);
-    void onPortSettingsChanged(OMX_U32 portIndex);
-
-    void setState(State newState);
-
-    status_t init();
-    void initOutputFormat(const sp<MetaData> &inputFormat);
-    status_t initNativeWindow();
-
-    void initNativeWindowCrop();
-
-    void dumpPortStatus(OMX_U32 portIndex);
-
-    status_t configureCodec(const sp<MetaData> &meta);
-
-    status_t waitForBufferFilled_l();
-
-    int64_t getDecodingTimeUs();
-
-    status_t parseHEVCCodecSpecificData(
-            const void *data, size_t size,
-            unsigned *profile, unsigned *level);
-    status_t parseAVCCodecSpecificData(
-            const void *data, size_t size,
-            unsigned *profile, unsigned *level);
-
-    status_t stopOmxComponent_l();
-
-    OMXCodec(const OMXCodec &);
-    OMXCodec &operator=(const OMXCodec &);
-};
-
-struct CodecCapabilities {
-    enum {
-        kFlagSupportsAdaptivePlayback = 1 << 0,
-    };
-
-    String8 mComponentName;
-    Vector<CodecProfileLevel> mProfileLevels;
-    Vector<OMX_U32> mColorFormats;
-    uint32_t mFlags;
-};
-
-// Return a vector of componentNames with supported profile/level pairs
-// supporting the given mime type, if queryDecoders==true, returns components
-// that decode content of the given type, otherwise returns components
-// that encode content of the given type.
-// profile and level indications only make sense for h.263, mpeg4 and avc
-// video.
-// If hwCodecOnly==true, only returns hardware-based components, software and
-// hardware otherwise.
-// The profile/level values correspond to
-// OMX_VIDEO_H263PROFILETYPE, OMX_VIDEO_MPEG4PROFILETYPE,
-// OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263LEVELTYPE, OMX_VIDEO_MPEG4LEVELTYPE
-// and OMX_VIDEO_AVCLEVELTYPE respectively.
-
-status_t QueryCodecs(
-        const sp<IOMX> &omx,
-        const char *mimeType, bool queryDecoders, bool hwCodecOnly,
-        Vector<CodecCapabilities> *results);
-
-status_t QueryCodecs(
-        const sp<IOMX> &omx,
-        const char *mimeType, bool queryDecoders,
-        Vector<CodecCapabilities> *results);
-
-status_t QueryCodec(
-        const sp<IOMX> &omx,
-        const char *componentName, const char *mime,
-        bool isEncoder,
-        CodecCapabilities *caps);
-
-}  // namespace android
-
-#endif  // OMX_CODEC_H_
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index cae5560..2270c85 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -119,11 +119,8 @@
 
 typedef SingleStateQueue<AudioPlaybackRate> PlaybackRateQueue;
 
-
 typedef SingleStateQueue<ExtendedTimestamp> ExtendedTimestampQueue;
 
-typedef SingleStateQueue<AudioTimestamp> TimestampQueue;
-
 // ----------------------------------------------------------------------------
 
 // Important: do not add any virtual methods, including ~
@@ -178,9 +175,7 @@
                 uint16_t    mPad2;           // unused
 
                 // server write-only, client read
-                ExtendedTimestampQueue::Shared mExtendedTimestampQueue; // capture
-                TimestampQueue::Shared mTimestampQueue; // playback
-
+                ExtendedTimestampQueue::Shared mExtendedTimestampQueue;
 public:
 
     volatile    int32_t     mFlags;         // combinations of CBLK_*
@@ -338,10 +333,7 @@
             size_t frameSize, bool clientInServer = false)
         : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
           clientInServer),
-          mPlaybackRateMutator(&cblk->mPlaybackRateQueue),
-          mTimestampObserver(&cblk->mTimestampQueue) {
-    }
-
+          mPlaybackRateMutator(&cblk->mPlaybackRateQueue) { }
     virtual ~AudioTrackClientProxy() { }
 
     // No barriers on the following operations, so the ordering of loads/stores
@@ -365,20 +357,6 @@
         mPlaybackRateMutator.push(playbackRate);
     }
 
-    status_t    getTimestamp(AudioTimestamp *timestamp) {
-        if (timestamp == nullptr) {
-            return BAD_VALUE;
-        }
-        (void) mTimestampObserver.poll(mTimestamp);
-        // if no data is pushed by server, mTimestamp should be initialized by its constructor
-        // to all zero elements.
-        if (mTimestamp.mTime.tv_sec == 0 && mTimestamp.mTime.tv_nsec == 0) {
-            return WOULD_BLOCK;
-        }
-        *timestamp = mTimestamp;
-        return OK;
-    }
-
     virtual void flush();
 
     virtual uint32_t    getUnderrunFrames() const {
@@ -396,8 +374,6 @@
 
 private:
     PlaybackRateQueue::Mutator   mPlaybackRateMutator;
-    TimestampQueue::Observer mTimestampObserver;
-    AudioTimestamp mTimestamp;
 };
 
 class StaticAudioTrackClientProxy : public AudioTrackClientProxy {
@@ -546,8 +522,7 @@
             size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
         : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer),
           mPlaybackRateObserver(&cblk->mPlaybackRateQueue),
-          mUnderrunCount(0), mUnderrunning(false),
-          mTimestampMutator(&cblk->mTimestampQueue) {
+          mUnderrunCount(0), mUnderrunning(false) {
         mCblk->mSampleRate = sampleRate;
         mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
     }
@@ -587,11 +562,6 @@
     // Return the playback speed and pitch read atomically. Not multi-thread safe on server side.
     AudioPlaybackRate getPlaybackRate();
 
-    // Expose timestamp to client proxy. Should only be called by a single thread.
-                   void setTimestamp(const AudioTimestamp &timestamp) {
-                       mTimestampMutator.push(timestamp);
-                   }
-
 private:
     AudioPlaybackRate             mPlaybackRate;  // last observed playback rate
     PlaybackRateQueue::Observer   mPlaybackRateObserver;
@@ -599,8 +569,6 @@
     // The server keeps a copy here where it is safe from the client.
     uint32_t                      mUnderrunCount; // echoed to mCblk
     bool                          mUnderrunning;  // used to detect edge of underrun
-
-    TimestampQueue::Mutator       mTimestampMutator;
 };
 
 class StaticAudioTrackServerProxy : public AudioTrackServerProxy {
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index c095724..479ccbb 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -31,6 +31,7 @@
     mediaplayer.cpp \
     IMediaCodecList.cpp \
     IMediaCodecService.cpp \
+    IMediaDrmService.cpp \
     IMediaHTTPConnection.cpp \
     IMediaHTTPService.cpp \
     IMediaLogService.cpp \
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index bd229c8..b2a5f14 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -2169,6 +2169,11 @@
     // Set false here to cover all the error return cases.
     mPreviousTimestampValid = false;
 
+    // FIXME not implemented for fast tracks; should use proxy and SSQ
+    if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
+        return INVALID_OPERATION;
+    }
+
     switch (mState) {
     case STATE_ACTIVE:
     case STATE_PAUSED:
@@ -2198,10 +2203,7 @@
 
     // 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.
-
-    // FastTrack timestamps are read through shared memory; otherwise use Binder.
-    status_t status = (mFlags & AUDIO_OUTPUT_FLAG_FAST) ?
-            mProxy->getTimestamp(&timestamp) : mAudioTrack->getTimestamp(timestamp);
+    status_t status = mAudioTrack->getTimestamp(timestamp);
     if (status != NO_ERROR) {
         ALOGV_IF(status != WOULD_BLOCK, "getTimestamp error:%#x", status);
         return status;
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 79059c6..26dd2c9 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -95,7 +95,7 @@
     }
 
     virtual ssize_t decrypt(
-            bool secure,
+            DestinationType dstType,
             const uint8_t key[16],
             const uint8_t iv[16],
             CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
@@ -105,7 +105,7 @@
             AString *errorDetailMsg) {
         Parcel data, reply;
         data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
-        data.writeInt32(secure);
+        data.writeInt32((int32_t)dstType);
         data.writeInt32(mode);
         data.writeInt32(pattern.mEncryptBlocks);
         data.writeInt32(pattern.mSkipBlocks);
@@ -136,8 +136,12 @@
         data.writeInt32(numSubSamples);
         data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
 
-        if (secure) {
+        if (dstType == kDestinationTypeNativeHandle) {
+            data.writeNativeHandle(static_cast<native_handle_t *>(dstPtr));
+        } else if (dstType == kDestinationTypeOpaqueHandle) {
             data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr)));
+        } else {
+            dstType = kDestinationTypeVmPointer;
         }
 
         remote()->transact(DECRYPT, data, &reply);
@@ -148,7 +152,7 @@
             errorDetailMsg->setTo(reply.readCString());
         }
 
-        if (!secure && result >= 0) {
+        if (dstType == kDestinationTypeVmPointer && result >= 0) {
             reply.read(dstPtr, result);
         }
 
@@ -276,7 +280,7 @@
         {
             CHECK_INTERFACE(ICrypto, data, reply);
 
-            bool secure = data.readInt32() != 0;
+            DestinationType dstType = (DestinationType)data.readInt32();
             CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
             CryptoPlugin::Pattern pattern;
             pattern.mEncryptBlocks = data.readInt32();
@@ -306,10 +310,16 @@
                     subSamples,
                     sizeof(CryptoPlugin::SubSample) * numSubSamples);
 
-            void *secureBufferId, *dstPtr;
-            if (secure) {
+            native_handle_t *nativeHandle = NULL;
+            void *secureBufferId = NULL, *dstPtr;
+            if (dstType == kDestinationTypeNativeHandle) {
+                nativeHandle = data.readNativeHandle();
+                dstPtr = static_cast<void *>(nativeHandle);
+            } else if (dstType == kDestinationTypeOpaqueHandle) {
                 secureBufferId = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
+                dstPtr = secureBufferId;
             } else {
+                dstType = kDestinationTypeVmPointer;
                 dstPtr = malloc(totalSize);
             }
 
@@ -340,13 +350,13 @@
                 result = -EINVAL;
             } else {
                 result = decrypt(
-                    secure,
+                    dstType,
                     key,
                     iv,
                     mode, pattern,
                     sharedBuffer, offset,
                     subSamples, numSubSamples,
-                    secure ? secureBufferId : dstPtr,
+                    dstPtr,
                     &errorDetailMsg);
             }
 
@@ -356,13 +366,21 @@
                 reply->writeCString(errorDetailMsg.c_str());
             }
 
-            if (!secure) {
+            if (dstType == kDestinationTypeVmPointer) {
                 if (result >= 0) {
                     CHECK_LE(result, static_cast<ssize_t>(totalSize));
                     reply->write(dstPtr, result);
                 }
                 free(dstPtr);
                 dstPtr = NULL;
+            } else if (dstType == kDestinationTypeNativeHandle) {
+                int err;
+                if ((err = native_handle_close(nativeHandle)) < 0) {
+                    ALOGW("secure buffer native_handle_close failed: %d", err);
+                }
+                if ((err = native_handle_delete(nativeHandle)) < 0) {
+                    ALOGW("secure buffer native_handle_delete failed: %d", err);
+                }
             }
 
             delete[] subSamples;
diff --git a/media/libmedia/IMediaDrmService.cpp b/media/libmedia/IMediaDrmService.cpp
new file mode 100644
index 0000000..9b6ecfd
--- /dev/null
+++ b/media/libmedia/IMediaDrmService.cpp
@@ -0,0 +1,88 @@
+/*
+**
+** Copyright 2015, 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 <binder/Parcel.h>
+#include <binder/IMemory.h>
+#include <media/ICrypto.h>
+#include <media/IDrm.h>
+#include <media/IMediaDrmService.h>
+
+#include <utils/Errors.h>  // for status_t
+#include <utils/String8.h>
+
+namespace android {
+
+enum {
+    MAKE_CRYPTO = IBinder::FIRST_CALL_TRANSACTION,
+    MAKE_DRM,
+};
+
+class BpMediaDrmService: public BpInterface<IMediaDrmService>
+{
+public:
+    BpMediaDrmService(const sp<IBinder>& impl)
+        : BpInterface<IMediaDrmService>(impl)
+    {
+    }
+
+    virtual sp<ICrypto> makeCrypto() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaDrmService::getInterfaceDescriptor());
+        remote()->transact(MAKE_CRYPTO, data, &reply);
+        return interface_cast<ICrypto>(reply.readStrongBinder());
+    }
+
+    virtual sp<IDrm> makeDrm() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaDrmService::getInterfaceDescriptor());
+        remote()->transact(MAKE_DRM, data, &reply);
+        return interface_cast<IDrm>(reply.readStrongBinder());
+    }
+
+};
+
+IMPLEMENT_META_INTERFACE(MediaDrmService, "android.media.IMediaDrmService");
+
+// ----------------------------------------------------------------------
+
+status_t BnMediaDrmService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case MAKE_CRYPTO: {
+            CHECK_INTERFACE(IMediaDrmService, data, reply);
+            sp<ICrypto> crypto = makeCrypto();
+            reply->writeStrongBinder(IInterface::asBinder(crypto));
+            return NO_ERROR;
+        } break;
+        case MAKE_DRM: {
+            CHECK_INTERFACE(IMediaDrmService, data, reply);
+            sp<IDrm> drm = makeDrm();
+            reply->writeStrongBinder(IInterface::asBinder(drm));
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace android
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 550b506..9a7dff6 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -37,7 +37,7 @@
     GET_CONFIG,
     SET_CONFIG,
     GET_STATE,
-    ENABLE_GRAPHIC_BUFFERS,
+    ENABLE_NATIVE_BUFFERS,
     USE_BUFFER,
     USE_GRAPHIC_BUFFER,
     CREATE_INPUT_SURFACE,
@@ -46,7 +46,7 @@
     SIGNAL_END_OF_INPUT_STREAM,
     STORE_META_DATA_IN_BUFFERS,
     PREPARE_FOR_ADAPTIVE_PLAYBACK,
-    ALLOC_BUFFER,
+    ALLOC_SECURE_BUFFER,
     ALLOC_BUFFER_WITH_BACKUP,
     FREE_BUFFER,
     FILL_BUFFER,
@@ -217,14 +217,15 @@
         return reply.readInt32();
     }
 
-    virtual status_t enableGraphicBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+    virtual status_t enableNativeBuffers(
+            node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
         data.writeInt32((int32_t)node);
         data.writeInt32(port_index);
+        data.writeInt32((uint32_t)graphic);
         data.writeInt32((uint32_t)enable);
-        remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply);
+        remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
 
         status_t err = reply.readInt32();
         return err;
@@ -453,26 +454,31 @@
     }
 
 
-    virtual status_t allocateBuffer(
+    virtual status_t allocateSecureBuffer(
             node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer, void **buffer_data) {
+            buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
         data.writeInt32((int32_t)node);
         data.writeInt32(port_index);
         data.writeInt64(size);
-        remote()->transact(ALLOC_BUFFER, data, &reply);
+        remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
 
         status_t err = reply.readInt32();
         if (err != OK) {
             *buffer = 0;
-
+            *buffer_data = NULL;
+            *native_handle = NULL;
             return err;
         }
 
         *buffer = (buffer_id)reply.readInt32();
         *buffer_data = (void *)reply.readInt64();
-
+        if (*buffer_data == NULL) {
+            *native_handle = reply.readNativeHandle();
+        } else {
+            *native_handle = NULL;
+        }
         return err;
     }
 
@@ -754,15 +760,16 @@
             return NO_ERROR;
         }
 
-        case ENABLE_GRAPHIC_BUFFERS:
+        case ENABLE_NATIVE_BUFFERS:
         {
             CHECK_OMX_INTERFACE(IOMX, data, reply);
 
             node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
+            OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
 
-            status_t err = enableGraphicBuffers(node, port_index, enable);
+            status_t err = enableNativeBuffers(node, port_index, graphic, enable);
             reply->writeInt32(err);
 
             return NO_ERROR;
@@ -965,7 +972,7 @@
             OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
             OMX_U32 audio_hw_sync = data.readInt32();
 
-            native_handle_t *sideband_handle;
+            native_handle_t *sideband_handle = NULL;
             status_t err = configureVideoTunnelMode(
                     node, port_index, tunneled, audio_hw_sync, &sideband_handle);
             reply->writeInt32(err);
@@ -974,7 +981,7 @@
             return NO_ERROR;
         }
 
-        case ALLOC_BUFFER:
+        case ALLOC_SECURE_BUFFER:
         {
             CHECK_OMX_INTERFACE(IOMX, data, reply);
 
@@ -989,14 +996,18 @@
             size_t size = data.readInt64();
 
             buffer_id buffer;
-            void *buffer_data;
-            status_t err = allocateBuffer(
-                    node, port_index, size, &buffer, &buffer_data);
+            void *buffer_data = NULL;
+            native_handle_t *native_handle = NULL;
+            status_t err = allocateSecureBuffer(
+                    node, port_index, size, &buffer, &buffer_data, &native_handle);
             reply->writeInt32(err);
 
             if (err == OK) {
                 reply->writeInt32((int32_t)buffer);
                 reply->writeInt64((uintptr_t)buffer_data);
+                if (buffer_data == NULL) {
+                    reply->writeNativeHandle(native_handle);
+                }
             }
 
             return NO_ERROR;
diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp
index b57f6ef..9165b9d 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/media/libmediaplayerservice/Crypto.cpp
@@ -235,7 +235,7 @@
 }
 
 ssize_t Crypto::decrypt(
-        bool secure,
+        DestinationType dstType,
         const uint8_t key[16],
         const uint8_t iv[16],
         CryptoPlugin::Mode mode,
@@ -257,7 +257,8 @@
     const void *srcPtr = static_cast<uint8_t *>(sharedBuffer->pointer()) + offset;
 
     return mPlugin->decrypt(
-            secure, key, iv, mode, pattern, srcPtr, subSamples, numSubSamples, dstPtr,
+            dstType != kDestinationTypeVmPointer,
+            key, iv, mode, pattern, srcPtr, subSamples, numSubSamples, dstPtr,
             errorDetailMsg);
 }
 
diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h
index 7705f30..7d181d3 100644
--- a/media/libmediaplayerservice/Crypto.h
+++ b/media/libmediaplayerservice/Crypto.h
@@ -50,7 +50,7 @@
     virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId);
 
     virtual ssize_t decrypt(
-            bool secure,
+            DestinationType dstType,
             const uint8_t key[16],
             const uint8_t iv[16],
             CryptoPlugin::Mode mode,
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index a049a30..0e6a6e6 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -91,6 +91,7 @@
         const sp<AMessage> &notify,
         uint32_t flags)
     : mAudioSink(sink),
+      mUseVirtualAudioSink(false),
       mNotify(notify),
       mFlags(flags),
       mNumFramesWritten(0),
@@ -1020,6 +1021,15 @@
 // Calculate duration of pending samples if played at normal rate (i.e., 1.0).
 int64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) {
     int64_t writtenAudioDurationUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten);
+    if (mUseVirtualAudioSink) {
+        int64_t nowUs = ALooper::GetNowUs();
+        int64_t mediaUs;
+        if (mMediaClock->getMediaTime(nowUs, &mediaUs) != OK) {
+            return 0ll;
+        } else {
+            return writtenAudioDurationUs - (mediaUs - mAudioFirstAnchorTimeMediaUs);
+        }
+    }
     return writtenAudioDurationUs - mAudioSink->getPlayedOutDurationUs(nowUs);
 }
 
@@ -1054,6 +1064,7 @@
         if (nowUs >= mNextAudioClockUpdateTimeUs) {
             int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs);
             mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs);
+            mUseVirtualAudioSink = false;
             mNextAudioClockUpdateTimeUs = nowUs + kMinimumAudioClockUpdatePeriodUs;
         }
     } else {
@@ -1070,6 +1081,7 @@
             // and it's paced by system clock.
             ALOGW("AudioSink stuck. ARE YOU CONNECTED TO AUDIO OUT? Switching to system clock.");
             mMediaClock->updateAnchor(mAudioFirstAnchorTimeMediaUs, nowUs, mediaTimeUs);
+            mUseVirtualAudioSink = true;
         }
     }
     mAnchorNumFramesWritten = mNumFramesWritten;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 1bc9c97..c3ce511 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -134,6 +134,7 @@
     static const int64_t kMinPositionUpdateDelayUs;
 
     sp<MediaPlayerBase::AudioSink> mAudioSink;
+    bool mUseVirtualAudioSink;
     sp<AMessage> mNotify;
     Mutex mLock;
     uint32_t mFlags;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index aab4fea..0dc5d4c 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -828,22 +828,32 @@
                 info.mStatus = BufferInfo::OWNED_BY_US;
                 info.mFenceFd = -1;
                 info.mRenderInfo = NULL;
+                info.mNativeHandle = NULL;
 
                 uint32_t requiresAllocateBufferBit =
                     (portIndex == kPortIndexInput)
                         ? kRequiresAllocateBufferOnInputPorts
                         : kRequiresAllocateBufferOnOutputPorts;
 
-                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
-                        || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())) {
+                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
                     mem.clear();
 
-                    void *ptr;
-                    err = mOMX->allocateBuffer(
+                    void *ptr = NULL;
+                    native_handle_t *native_handle = NULL;
+                    err = mOMX->allocateSecureBuffer(
                             mNode, portIndex, bufSize, &info.mBufferID,
-                            &ptr);
+                            &ptr, &native_handle);
 
-                    info.mData = new ABuffer(ptr, bufSize);
+                    // TRICKY: this representation is unorthodox, but ACodec requires
+                    // an ABuffer with a proper size to validate range offsets and lengths.
+                    // Since mData is never referenced for secure input, it is used to store
+                    // either the pointer to the secure buffer, or the opaque handle as on
+                    // some devices ptr is actually an opaque handle, not a pointer.
+
+                    // TRICKY2: use native handle as the base of the ABuffer if received one,
+                    // because Widevine source only receives these base addresses.
+                    info.mData = new ABuffer(ptr != NULL ? ptr : (void *)native_handle, bufSize);
+                    info.mNativeHandle = NativeHandle::create(native_handle, true /* ownsHandle */);
                 } else if (mQuirks & requiresAllocateBufferBit) {
                     err = mOMX->allocateBufferWithBackup(
                             mNode, portIndex, mem, &info.mBufferID, allottedSize);
@@ -877,7 +887,7 @@
 
     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
         const BufferInfo &info = mBuffers[portIndex][i];
-        desc->addBuffer(info.mBufferID, info.mData, info.mMemRef);
+        desc->addBuffer(info.mBufferID, info.mData, info.mNativeHandle, info.mMemRef);
     }
 
     notify->setObject("portDesc", desc);
@@ -1775,6 +1785,14 @@
             mFlags |= kFlagIsGrallocUsageProtected;
             mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
         }
+
+        if (mFlags & kFlagIsSecure) {
+            // use native_handles for secure input buffers
+            err = mOMX->enableNativeBuffers(
+                    mNode, kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
+            ALOGI_IF(err != OK, "falling back to non-native_handles");
+            err = OK; // ignore error for now
+        }
     }
     if (haveNativeWindow) {
         sp<ANativeWindow> nativeWindow =
@@ -1986,7 +2004,8 @@
                         inputFormat->setInt32("adaptive-playback", false);
                     }
                     if (err == OK) {
-                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
+                        err = mOMX->enableNativeBuffers(
+                                mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
                     }
                     if (mFlags & kFlagIsGrallocUsageProtected) {
                         // fallback is not supported for protected playback
@@ -3880,10 +3899,10 @@
 
 status_t ACodec::initNativeWindow() {
     if (mNativeWindow != NULL) {
-        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
+        return mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
     }
 
-    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
+    mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
     return OK;
 }
 
@@ -4647,9 +4666,11 @@
 }
 
 void ACodec::PortDescription::addBuffer(
-        IOMX::buffer_id id, const sp<ABuffer> &buffer, const sp<RefBase> &memRef) {
+        IOMX::buffer_id id, const sp<ABuffer> &buffer,
+        const sp<NativeHandle> &handle, const sp<RefBase> &memRef) {
     mBufferIDs.push_back(id);
     mBuffers.push_back(buffer);
+    mHandles.push_back(handle);
     mMemRefs.push_back(memRef);
 }
 
@@ -4665,6 +4686,10 @@
     return mBuffers.itemAt(index);
 }
 
+sp<NativeHandle> ACodec::PortDescription::handleAt(size_t index) const {
+    return mHandles.itemAt(index);
+}
+
 sp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const {
     return mMemRefs.itemAt(index);
 }
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 2df69b4..fd4ed58 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -45,7 +45,6 @@
         NuCachedSource2.cpp               \
         NuMediaExtractor.cpp              \
         OMXClient.cpp                     \
-        OMXCodec.cpp                      \
         OggExtractor.cpp                  \
         ProcessInfo.cpp                   \
         SampleIterator.cpp                \
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index d302f82..64d4302 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -792,10 +792,14 @@
 void CameraSource::stopCameraRecording() {
     ALOGV("stopCameraRecording");
     if (mCameraFlags & FLAGS_HOT_CAMERA) {
-        mCameraRecordingProxy->stopRecording();
+        if (mCameraRecordingProxy != 0) {
+            mCameraRecordingProxy->stopRecording();
+        }
     } else {
-        mCamera->setListener(NULL);
-        mCamera->stopRecording();
+        if (mCamera != 0) {
+            mCamera->setListener(NULL);
+            mCamera->stopRecording();
+        }
     }
 }
 
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index ce67d78..fb1f401 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1357,6 +1357,7 @@
                         info.mBufferID = portDesc->bufferIDAt(i);
                         info.mOwnedByClient = false;
                         info.mData = portDesc->bufferAt(i);
+                        info.mNativeHandle = portDesc->handleAt(i);
                         info.mMemRef = portDesc->memRefAt(i);
 
                         if (portIndex == kPortIndexInput && mCrypto != NULL) {
@@ -2493,8 +2494,18 @@
         AString *errorDetailMsg;
         CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
 
+        void *dst_pointer = info->mData->base();
+        ICrypto::DestinationType dst_type = ICrypto::kDestinationTypeOpaqueHandle;
+
+        if (info->mNativeHandle != NULL) {
+            dst_pointer = (void *)info->mNativeHandle.get();
+            dst_type = ICrypto::kDestinationTypeNativeHandle;
+        } else if ((mFlags & kFlagIsSecure) == 0) {
+            dst_type = ICrypto::kDestinationTypeVmPointer;
+        }
+
         ssize_t result = mCrypto->decrypt(
-                (mFlags & kFlagIsSecure) != 0,
+                dst_type,
                 key,
                 iv,
                 mode,
@@ -2503,7 +2514,7 @@
                 offset,
                 subSamples,
                 numSubSamples,
-                info->mData->base(),
+                dst_pointer,
                 errorDetailMsg);
 
         if (result < 0) {
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index e69890d..50f235e 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -82,8 +82,8 @@
             node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
             OMX_U32 audioHwSync, native_handle_t **sidebandHandle);
 
-    virtual status_t enableGraphicBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable);
+    virtual status_t enableNativeBuffers(
+            node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable);
 
     virtual status_t getGraphicBufferUsage(
             node_id node, OMX_U32 port_index, OMX_U32* usage);
@@ -114,9 +114,9 @@
 
     virtual status_t signalEndOfInputStream(node_id node);
 
-    virtual status_t allocateBuffer(
+    virtual status_t allocateSecureBuffer(
             node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer, void **buffer_data);
+            buffer_id *buffer, void **buffer_data, native_handle_t **native_handle);
 
     virtual status_t allocateBufferWithBackup(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
@@ -310,9 +310,9 @@
             node, portIndex, enable, audioHwSync, sidebandHandle);
 }
 
-status_t MuxOMX::enableGraphicBuffers(
-        node_id node, OMX_U32 port_index, OMX_BOOL enable) {
-    return getOMX(node)->enableGraphicBuffers(node, port_index, enable);
+status_t MuxOMX::enableNativeBuffers(
+        node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
+    return getOMX(node)->enableNativeBuffers(node, port_index, graphic, enable);
 }
 
 status_t MuxOMX::getGraphicBufferUsage(
@@ -366,11 +366,11 @@
     return getOMX(node)->signalEndOfInputStream(node);
 }
 
-status_t MuxOMX::allocateBuffer(
+status_t MuxOMX::allocateSecureBuffer(
         node_id node, OMX_U32 port_index, size_t size,
-        buffer_id *buffer, void **buffer_data) {
-    return getOMX(node)->allocateBuffer(
-            node, port_index, size, buffer, buffer_data);
+        buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
+    return getOMX(node)->allocateSecureBuffer(
+            node, port_index, size, buffer, buffer_data, native_handle);
 }
 
 status_t MuxOMX::allocateBufferWithBackup(
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
deleted file mode 100644
index 1b62335..0000000
--- a/media/libstagefright/OMXCodec.cpp
+++ /dev/null
@@ -1,4417 +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.
- */
-
-#include <inttypes.h>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "OMXCodec"
-
-#ifdef __LP64__
-#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
-#endif
-
-#include <utils/Log.h>
-
-#include "include/AACEncoder.h"
-
-#include "include/ESDS.h"
-
-#include <binder/IServiceManager.h>
-#include <binder/MemoryDealer.h>
-#include <binder/ProcessState.h>
-#include <HardwareAPI.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/IMediaPlayerService.h>
-#include <media/stagefright/ACodec.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaCodecList.h>
-#include <media/stagefright/MediaExtractor.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/OMXCodec.h>
-#include <media/stagefright/SurfaceUtils.h>
-#include <media/stagefright/Utils.h>
-#include <media/stagefright/SkipCutBuffer.h>
-#include <utils/Vector.h>
-
-#include <OMX_AudioExt.h>
-#include <OMX_Component.h>
-#include <OMX_IndexExt.h>
-#include <OMX_VideoExt.h>
-#include <OMX_AsString.h>
-
-#include "include/avc_utils.h"
-
-namespace android {
-
-// Treat time out as an error if we have not received any output
-// buffers after 3 seconds.
-const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL;
-
-// OMX Spec defines less than 50 color formats. If the query for
-// color format is executed for more than kMaxColorFormatSupported,
-// the query will fail to avoid looping forever.
-// 1000 is more than enough for us to tell whether the omx
-// component in question is buggy or not.
-const static uint32_t kMaxColorFormatSupported = 1000;
-
-#define FACTORY_CREATE_ENCODER(name) \
-static sp<IMediaSource> Make##name(const sp<IMediaSource> &source, const sp<MetaData> &meta) { \
-    return new name(source, meta); \
-}
-
-#define FACTORY_REF(name) { #name, Make##name },
-
-FACTORY_CREATE_ENCODER(AACEncoder)
-
-static sp<IMediaSource> InstantiateSoftwareEncoder(
-        const char *name, const sp<IMediaSource> &source,
-        const sp<MetaData> &meta) {
-    struct FactoryInfo {
-        const char *name;
-        sp<IMediaSource> (*CreateFunc)(const sp<IMediaSource> &, const sp<MetaData> &);
-    };
-
-    static const FactoryInfo kFactoryInfo[] = {
-        FACTORY_REF(AACEncoder)
-    };
-    for (size_t i = 0;
-         i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
-        if (!strcmp(name, kFactoryInfo[i].name)) {
-            return (*kFactoryInfo[i].CreateFunc)(source, meta);
-        }
-    }
-
-    return NULL;
-}
-
-#undef FACTORY_CREATE_ENCODER
-#undef FACTORY_REF
-
-#define CODEC_LOGI(x, ...) ALOGI("[%s] " x, mComponentName, ##__VA_ARGS__)
-#define CODEC_LOGV(x, ...) ALOGV("[%s] " x, mComponentName, ##__VA_ARGS__)
-#define CODEC_LOGW(x, ...) ALOGW("[%s] " x, mComponentName, ##__VA_ARGS__)
-#define CODEC_LOGE(x, ...) ALOGE("[%s] " x, mComponentName, ##__VA_ARGS__)
-
-struct OMXCodecObserver : public BnOMXObserver {
-    OMXCodecObserver() {
-    }
-
-    void setCodec(const sp<OMXCodec> &target) {
-        mTarget = target;
-    }
-
-    // from IOMXObserver
-    virtual void onMessages(const std::list<omx_message> &messages) {
-        sp<OMXCodec> codec = mTarget.promote();
-
-        if (codec.get() != NULL) {
-            Mutex::Autolock autoLock(codec->mLock);
-            for (std::list<omx_message>::const_iterator it = messages.cbegin();
-                  it != messages.cend(); ++it) {
-                codec->on_message(*it);
-            }
-            codec.clear();
-        }
-    }
-
-protected:
-    virtual ~OMXCodecObserver() {}
-
-private:
-    wp<OMXCodec> mTarget;
-
-    OMXCodecObserver(const OMXCodecObserver &);
-    OMXCodecObserver &operator=(const OMXCodecObserver &);
-};
-
-template<class T>
-static void InitOMXParams(T *params) {
-    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(sizeof(OMX_PTR) == 4); // check OMX_PTR is 4 bytes.
-    params->nSize = sizeof(T);
-    params->nVersion.s.nVersionMajor = 1;
-    params->nVersion.s.nVersionMinor = 0;
-    params->nVersion.s.nRevision = 0;
-    params->nVersion.s.nStep = 0;
-}
-
-static bool IsSoftwareCodec(const char *componentName) {
-    if (!strncmp("OMX.google.", componentName, 11)) {
-        return true;
-    }
-
-    if (!strncmp("OMX.", componentName, 4)) {
-        return false;
-    }
-
-    return true;
-}
-
-// A sort order in which OMX software codecs are first, followed
-// by other (non-OMX) software codecs, followed by everything else.
-static int CompareSoftwareCodecsFirst(
-        const OMXCodec::CodecNameAndQuirks *elem1,
-        const OMXCodec::CodecNameAndQuirks *elem2) {
-    bool isOMX1 = !strncmp(elem1->mName.string(), "OMX.", 4);
-    bool isOMX2 = !strncmp(elem2->mName.string(), "OMX.", 4);
-
-    bool isSoftwareCodec1 = IsSoftwareCodec(elem1->mName.string());
-    bool isSoftwareCodec2 = IsSoftwareCodec(elem2->mName.string());
-
-    if (isSoftwareCodec1) {
-        if (!isSoftwareCodec2) { return -1; }
-
-        if (isOMX1) {
-            if (isOMX2) { return 0; }
-
-            return -1;
-        } else {
-            if (isOMX2) { return 0; }
-
-            return 1;
-        }
-
-        return -1;
-    }
-
-    if (isSoftwareCodec2) {
-        return 1;
-    }
-
-    return 0;
-}
-
-// static
-void OMXCodec::findMatchingCodecs(
-        const char *mime,
-        bool createEncoder, const char *matchComponentName,
-        uint32_t flags,
-        Vector<CodecNameAndQuirks> *matchingCodecs) {
-    matchingCodecs->clear();
-
-    const sp<IMediaCodecList> list = MediaCodecList::getInstance();
-    if (list == NULL) {
-        return;
-    }
-
-    size_t index = 0;
-    for (;;) {
-        ssize_t matchIndex =
-            list->findCodecByType(mime, createEncoder, index);
-
-        if (matchIndex < 0) {
-            break;
-        }
-
-        index = matchIndex + 1;
-
-        const sp<MediaCodecInfo> info = list->getCodecInfo(matchIndex);
-        CHECK(info != NULL);
-        const char *componentName = info->getCodecName();
-
-        // If a specific codec is requested, skip the non-matching ones.
-        if (matchComponentName && strcmp(componentName, matchComponentName)) {
-            continue;
-        }
-
-        // When requesting software-only codecs, only push software codecs
-        // When requesting hardware-only codecs, only push hardware codecs
-        // When there is request neither for software-only nor for
-        // hardware-only codecs, push all codecs
-        if (((flags & kSoftwareCodecsOnly) &&   IsSoftwareCodec(componentName)) ||
-            ((flags & kHardwareCodecsOnly) &&  !IsSoftwareCodec(componentName)) ||
-            (!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) {
-
-            ssize_t index = matchingCodecs->add();
-            CodecNameAndQuirks *entry = &matchingCodecs->editItemAt(index);
-            entry->mName = String8(componentName);
-            entry->mQuirks = getComponentQuirks(info);
-
-            ALOGV("matching '%s' quirks 0x%08x",
-                  entry->mName.string(), entry->mQuirks);
-        }
-    }
-
-    if (flags & kPreferSoftwareCodecs) {
-        matchingCodecs->sort(CompareSoftwareCodecsFirst);
-    }
-}
-
-// static
-uint32_t OMXCodec::getComponentQuirks(
-        const sp<MediaCodecInfo> &info) {
-    uint32_t quirks = 0;
-    if (info->hasQuirk("requires-allocate-on-input-ports")) {
-        quirks |= kRequiresAllocateBufferOnInputPorts;
-    }
-    if (info->hasQuirk("requires-allocate-on-output-ports")) {
-        quirks |= kRequiresAllocateBufferOnOutputPorts;
-    }
-    if (info->hasQuirk("output-buffers-are-unreadable")) {
-        quirks |= kOutputBuffersAreUnreadable;
-    }
-
-    return quirks;
-}
-
-// static
-sp<IMediaSource> OMXCodec::Create(
-        const sp<IOMX> &omx,
-        const sp<MetaData> &meta, bool createEncoder,
-        const sp<IMediaSource> &source,
-        const char *matchComponentName,
-        uint32_t flags,
-        const sp<ANativeWindow> &nativeWindow) {
-    int32_t requiresSecureBuffers;
-    if (source->getFormat()->findInt32(
-                kKeyRequiresSecureBuffers,
-                &requiresSecureBuffers)
-            && requiresSecureBuffers) {
-        flags |= kIgnoreCodecSpecificData;
-        flags |= kUseSecureInputBuffers;
-    }
-
-    const char *mime;
-    bool success = meta->findCString(kKeyMIMEType, &mime);
-    CHECK(success);
-
-    Vector<CodecNameAndQuirks> matchingCodecs;
-    findMatchingCodecs(
-            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
-
-    if (matchingCodecs.isEmpty()) {
-        ALOGV("No matching codecs! (mime: %s, createEncoder: %s, "
-                "matchComponentName: %s, flags: 0x%x)",
-                mime, createEncoder ? "true" : "false", matchComponentName, flags);
-        return NULL;
-    }
-
-    sp<OMXCodecObserver> observer = new OMXCodecObserver;
-    IOMX::node_id node = 0;
-
-    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
-        const char *componentNameBase = matchingCodecs[i].mName.string();
-        uint32_t quirks = matchingCodecs[i].mQuirks;
-        const char *componentName = componentNameBase;
-
-        AString tmp;
-        if (flags & kUseSecureInputBuffers) {
-            tmp = componentNameBase;
-            tmp.append(".secure");
-
-            componentName = tmp.c_str();
-        }
-
-        if (createEncoder) {
-            sp<IMediaSource> softwareCodec =
-                InstantiateSoftwareEncoder(componentName, source, meta);
-
-            if (softwareCodec != NULL) {
-                ALOGV("Successfully allocated software codec '%s'", componentName);
-
-                return softwareCodec;
-            }
-        }
-
-        ALOGV("Attempting to allocate OMX node '%s'", componentName);
-
-        if (!createEncoder
-                && (quirks & kOutputBuffersAreUnreadable)
-                && (flags & kClientNeedsFramebuffer)) {
-            if (strncmp(componentName, "OMX.SEC.", 8)) {
-                // For OMX.SEC.* decoders we can enable a special mode that
-                // gives the client access to the framebuffer contents.
-
-                ALOGW("Component '%s' does not give the client access to "
-                     "the framebuffer contents. Skipping.",
-                     componentName);
-
-                continue;
-            }
-        }
-
-        status_t err = omx->allocateNode(componentName, observer, &node);
-        if (err == OK) {
-            ALOGV("Successfully allocated OMX node '%s'", componentName);
-
-            sp<OMXCodec> codec = new OMXCodec(
-                    omx, node, quirks, flags,
-                    createEncoder, mime, componentName,
-                    source, nativeWindow);
-
-            observer->setCodec(codec);
-
-            err = codec->configureCodec(meta);
-            if (err == OK) {
-                return codec;
-            }
-
-            ALOGV("Failed to configure codec '%s'", componentName);
-        }
-    }
-
-    return NULL;
-}
-
-status_t OMXCodec::parseHEVCCodecSpecificData(
-        const void *data, size_t size,
-        unsigned *profile, unsigned *level) {
-    const uint8_t *ptr = (const uint8_t *)data;
-
-    // verify minimum size and configurationVersion == 1.
-    if (size < 23 || ptr[0] != 1) {
-        return ERROR_MALFORMED;
-    }
-
-    *profile = (ptr[1] & 31);
-    *level = ptr[12];
-
-    ptr += 22;
-    size -= 22;
-
-    size_t numofArrays = (char)ptr[0];
-    ptr += 1;
-    size -= 1;
-    size_t j = 0, i = 0;
-    for (i = 0; i < numofArrays; i++) {
-        if (size < 3) {
-            return ERROR_MALFORMED;
-        }
-        ptr += 1;
-        size -= 1;
-
-        // Num of nals
-        size_t numofNals = U16_AT(ptr);
-        ptr += 2;
-        size -= 2;
-
-        for (j = 0;j < numofNals;j++) {
-            if (size < 2) {
-                return ERROR_MALFORMED;
-            }
-
-            size_t length = U16_AT(ptr);
-
-            ptr += 2;
-            size -= 2;
-
-            if (size < length) {
-                return ERROR_MALFORMED;
-            }
-            addCodecSpecificData(ptr, length);
-
-            ptr += length;
-            size -= length;
-        }
-    }
-    return OK;
-}
-
-status_t OMXCodec::parseAVCCodecSpecificData(
-        const void *data, size_t size,
-        unsigned *profile, unsigned *level) {
-    const uint8_t *ptr = (const uint8_t *)data;
-
-    // verify minimum size and configurationVersion == 1.
-    if (size < 7 || ptr[0] != 1) {
-        return ERROR_MALFORMED;
-    }
-
-    *profile = ptr[1];
-    *level = ptr[3];
-
-    // There is decodable content out there that fails the following
-    // assertion, let's be lenient for now...
-    // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
-
-    size_t lengthSize __unused = 1 + (ptr[4] & 3);
-
-    // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
-    // violates it...
-    // CHECK((ptr[5] >> 5) == 7);  // reserved
-
-    size_t numSeqParameterSets = ptr[5] & 31;
-
-    ptr += 6;
-    size -= 6;
-
-    for (size_t i = 0; i < numSeqParameterSets; ++i) {
-        if (size < 2) {
-            return ERROR_MALFORMED;
-        }
-
-        size_t length = U16_AT(ptr);
-
-        ptr += 2;
-        size -= 2;
-
-        if (size < length) {
-            return ERROR_MALFORMED;
-        }
-
-        addCodecSpecificData(ptr, length);
-
-        ptr += length;
-        size -= length;
-    }
-
-    if (size < 1) {
-        return ERROR_MALFORMED;
-    }
-
-    size_t numPictureParameterSets = *ptr;
-    ++ptr;
-    --size;
-
-    for (size_t i = 0; i < numPictureParameterSets; ++i) {
-        if (size < 2) {
-            return ERROR_MALFORMED;
-        }
-
-        size_t length = U16_AT(ptr);
-
-        ptr += 2;
-        size -= 2;
-
-        if (size < length) {
-            return ERROR_MALFORMED;
-        }
-
-        addCodecSpecificData(ptr, length);
-
-        ptr += length;
-        size -= length;
-    }
-
-    return OK;
-}
-
-status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
-    ALOGV("configureCodec protected=%d",
-         (mFlags & kEnableGrallocUsageProtected) ? 1 : 0);
-
-    if (!(mFlags & kIgnoreCodecSpecificData)) {
-        uint32_t type;
-        const void *data;
-        size_t size;
-        if (meta->findData(kKeyESDS, &type, &data, &size)) {
-            ESDS esds((const char *)data, size);
-            CHECK_EQ(esds.InitCheck(), (status_t)OK);
-
-            const void *codec_specific_data;
-            size_t codec_specific_data_size;
-            esds.getCodecSpecificInfo(
-                    &codec_specific_data, &codec_specific_data_size);
-
-            addCodecSpecificData(
-                    codec_specific_data, codec_specific_data_size);
-        } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
-            // Parse the AVCDecoderConfigurationRecord
-
-            unsigned profile, level;
-            status_t err;
-            if ((err = parseAVCCodecSpecificData(
-                            data, size, &profile, &level)) != OK) {
-                ALOGE("Malformed AVC codec specific data.");
-                return err;
-            }
-
-            CODEC_LOGI(
-                    "AVC profile = %u (%s), level = %u",
-                    profile, AVCProfileToString(profile), level);
-        } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
-            // Parse the HEVCDecoderConfigurationRecord
-
-            unsigned profile, level;
-            status_t err;
-            if ((err = parseHEVCCodecSpecificData(
-                            data, size, &profile, &level)) != OK) {
-                ALOGE("Malformed HEVC codec specific data.");
-                return err;
-            }
-
-            CODEC_LOGI(
-                    "HEVC profile = %u , level = %u",
-                    profile, level);
-        } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
-            addCodecSpecificData(data, size);
-
-            CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
-            addCodecSpecificData(data, size);
-        } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
-            addCodecSpecificData(data, size);
-
-            CHECK(meta->findData(kKeyOpusCodecDelay, &type, &data, &size));
-            addCodecSpecificData(data, size);
-            CHECK(meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size));
-            addCodecSpecificData(data, size);
-        }
-    }
-
-    int32_t bitRate = 0;
-    if (mIsEncoder) {
-        CHECK(meta->findInt32(kKeyBitRate, &bitRate));
-    }
-    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
-        setAMRFormat(false /* isWAMR */, bitRate);
-    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
-        setAMRFormat(true /* isWAMR */, bitRate);
-    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
-        int32_t numChannels, sampleRate, aacProfile;
-        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
-        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
-
-        if (!meta->findInt32(kKeyAACProfile, &aacProfile)) {
-            aacProfile = OMX_AUDIO_AACObjectNull;
-        }
-
-        int32_t isADTS;
-        if (!meta->findInt32(kKeyIsADTS, &isADTS)) {
-            isADTS = false;
-        }
-
-        status_t err = setAACFormat(numChannels, sampleRate, bitRate, aacProfile, isADTS);
-        if (err != OK) {
-            CODEC_LOGE("setAACFormat() failed (err = %d)", err);
-            return err;
-        }
-    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_MPEG, mMIME)) {
-        int32_t numChannels, sampleRate;
-        if (meta->findInt32(kKeyChannelCount, &numChannels)
-                && meta->findInt32(kKeySampleRate, &sampleRate)) {
-            // Since we did not always check for these, leave them optional
-            // and have the decoder figure it all out.
-            setRawAudioFormat(
-                    mIsEncoder ? kPortIndexInput : kPortIndexOutput,
-                    sampleRate,
-                    numChannels);
-        }
-    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AC3, mMIME)) {
-        int32_t numChannels;
-        int32_t sampleRate;
-        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
-        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
-
-        status_t err = setAC3Format(numChannels, sampleRate);
-        if (err != OK) {
-            CODEC_LOGE("setAC3Format() failed (err = %d)", err);
-            return err;
-        }
-    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_ALAW, mMIME)
-            || !strcasecmp(MEDIA_MIMETYPE_AUDIO_G711_MLAW, mMIME)) {
-        // These are PCM-like formats with a fixed sample rate but
-        // a variable number of channels.
-
-        int32_t sampleRate;
-        int32_t numChannels;
-        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
-        if (!meta->findInt32(kKeySampleRate, &sampleRate)) {
-            sampleRate = 8000;
-        }
-
-        setG711Format(sampleRate, numChannels);
-    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mMIME)) {
-        CHECK(!mIsEncoder);
-
-        int32_t numChannels, sampleRate;
-        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
-        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
-
-        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
-    }
-
-    if (!strncasecmp(mMIME, "video/", 6)) {
-
-        if (mIsEncoder) {
-            setVideoInputFormat(mMIME, meta);
-        } else {
-            status_t err = setVideoOutputFormat(
-                    mMIME, meta);
-
-            if (err != OK) {
-                return err;
-            }
-        }
-    }
-
-    int32_t maxInputSize;
-    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
-        setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
-    }
-
-    initOutputFormat(meta);
-
-    if ((mFlags & kClientNeedsFramebuffer)
-            && !strncmp(mComponentName, "OMX.SEC.", 8)) {
-        // This appears to no longer be needed???
-
-        OMX_INDEXTYPE index;
-
-        status_t err =
-            mOMX->getExtensionIndex(
-                    mNode,
-                    "OMX.SEC.index.ThumbnailMode",
-                    &index);
-
-        if (err != OK) {
-            return err;
-        }
-
-        OMX_BOOL enable = OMX_TRUE;
-        err = mOMX->setConfig(mNode, index, &enable, sizeof(enable));
-
-        if (err != OK) {
-            CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') "
-                       "returned error 0x%08x", err);
-
-            return err;
-        }
-
-        mQuirks &= ~kOutputBuffersAreUnreadable;
-    }
-
-    if (mNativeWindow != NULL
-        && !mIsEncoder
-        && !strncasecmp(mMIME, "video/", 6)
-        && !strncmp(mComponentName, "OMX.", 4)) {
-        status_t err = initNativeWindow();
-        if (err != OK) {
-            return err;
-        }
-    }
-
-    return OK;
-}
-
-void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = portIndex;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus))
-        || (def.nBufferSize < size)) {
-        def.nBufferSize = size;
-    }
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    // Make sure the setting actually stuck.
-    if (portIndex == kPortIndexInput
-            && (mQuirks & kInputBufferSizesAreBogus)) {
-        CHECK_EQ(def.nBufferSize, size);
-    } else {
-        CHECK(def.nBufferSize >= size);
-    }
-}
-
-status_t OMXCodec::setVideoPortFormatType(
-        OMX_U32 portIndex,
-        OMX_VIDEO_CODINGTYPE compressionFormat,
-        OMX_COLOR_FORMATTYPE colorFormat) {
-    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
-    InitOMXParams(&format);
-    format.nPortIndex = portIndex;
-    format.nIndex = 0;
-    bool found = false;
-
-    OMX_U32 index = 0;
-    for (;;) {
-        format.nIndex = index;
-        status_t err = mOMX->getParameter(
-                mNode, OMX_IndexParamVideoPortFormat,
-                &format, sizeof(format));
-
-        if (err != OK) {
-            return err;
-        }
-
-        // The following assertion is violated by TI's video decoder.
-        // CHECK_EQ(format.nIndex, index);
-
-#if 1
-        CODEC_LOGV("portIndex: %u, index: %u, eCompressionFormat=%d eColorFormat=%d",
-             portIndex,
-             index, format.eCompressionFormat, format.eColorFormat);
-#endif
-
-        if (format.eCompressionFormat == compressionFormat
-                && format.eColorFormat == colorFormat) {
-            found = true;
-            break;
-        }
-
-        ++index;
-        if (index >= kMaxColorFormatSupported) {
-            CODEC_LOGE("color format %d or compression format %d is not supported",
-                colorFormat, compressionFormat);
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    if (!found) {
-        return UNKNOWN_ERROR;
-    }
-
-    CODEC_LOGV("found a match.");
-    status_t err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoPortFormat,
-            &format, sizeof(format));
-
-    return err;
-}
-
-static size_t getFrameSize(
-        OMX_COLOR_FORMATTYPE colorFormat, int32_t width, int32_t height) {
-    switch (colorFormat) {
-        case OMX_COLOR_FormatYCbYCr:
-        case OMX_COLOR_FormatCbYCrY:
-            return width * height * 2;
-
-        case OMX_COLOR_FormatYUV420Planar:
-        case OMX_COLOR_FormatYUV420SemiPlanar:
-        case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
-        /*
-        * FIXME: For the Opaque color format, the frame size does not
-        * need to be (w*h*3)/2. It just needs to
-        * be larger than certain minimum buffer size. However,
-        * currently, this opaque foramt has been tested only on
-        * YUV420 formats. If that is changed, then we need to revisit
-        * this part in the future
-        */
-        case OMX_COLOR_FormatAndroidOpaque:
-            return (width * height * 3) / 2;
-
-        default:
-            CHECK(!"Should not be here. Unsupported color format.");
-            break;
-    }
-    return 0;
-}
-
-status_t OMXCodec::findTargetColorFormat(
-        const sp<MetaData>& meta, OMX_COLOR_FORMATTYPE *colorFormat) {
-    ALOGV("findTargetColorFormat");
-    CHECK(mIsEncoder);
-
-    *colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
-    int32_t targetColorFormat;
-    if (meta->findInt32(kKeyColorFormat, &targetColorFormat)) {
-        *colorFormat = (OMX_COLOR_FORMATTYPE) targetColorFormat;
-    }
-
-    // Check whether the target color format is supported.
-    return isColorFormatSupported(*colorFormat, kPortIndexInput);
-}
-
-status_t OMXCodec::isColorFormatSupported(
-        OMX_COLOR_FORMATTYPE colorFormat, int portIndex) {
-    ALOGV("isColorFormatSupported: %d", static_cast<int>(colorFormat));
-
-    // Enumerate all the color formats supported by
-    // the omx component to see whether the given
-    // color format is supported.
-    OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
-    InitOMXParams(&portFormat);
-    portFormat.nPortIndex = portIndex;
-    OMX_U32 index = 0;
-    portFormat.nIndex = index;
-    while (true) {
-        if (OMX_ErrorNone != mOMX->getParameter(
-                mNode, OMX_IndexParamVideoPortFormat,
-                &portFormat, sizeof(portFormat))) {
-            break;
-        }
-        // Make sure that omx component does not overwrite
-        // the incremented index (bug 2897413).
-        CHECK_EQ(index, portFormat.nIndex);
-        if (portFormat.eColorFormat == colorFormat) {
-            CODEC_LOGV("Found supported color format: %d", portFormat.eColorFormat);
-            return OK;  // colorFormat is supported!
-        }
-        ++index;
-        portFormat.nIndex = index;
-
-        if (index >= kMaxColorFormatSupported) {
-            CODEC_LOGE("More than %u color formats are supported???", index);
-            break;
-        }
-    }
-
-    CODEC_LOGE("color format %d is not supported", colorFormat);
-    return UNKNOWN_ERROR;
-}
-
-void OMXCodec::setVideoInputFormat(
-        const char *mime, const sp<MetaData>& meta) {
-
-    int32_t width, height, frameRate, bitRate, stride, sliceHeight;
-    bool success = meta->findInt32(kKeyWidth, &width);
-    success = success && meta->findInt32(kKeyHeight, &height);
-    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
-    success = success && meta->findInt32(kKeyBitRate, &bitRate);
-    success = success && meta->findInt32(kKeyStride, &stride);
-    success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
-    CHECK(success);
-    CHECK(stride != 0);
-
-    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
-    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
-        compressionFormat = OMX_VIDEO_CodingAVC;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
-        compressionFormat = OMX_VIDEO_CodingHEVC;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
-        compressionFormat = OMX_VIDEO_CodingMPEG4;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
-        compressionFormat = OMX_VIDEO_CodingH263;
-    } else {
-        ALOGE("Not a supported video mime type: %s", mime);
-        CHECK(!"Should not be here. Not a supported video mime type.");
-    }
-
-    OMX_COLOR_FORMATTYPE colorFormat;
-    CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat));
-
-    status_t err;
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
-
-    //////////////////////// Input port /////////////////////////
-    CHECK_EQ(setVideoPortFormatType(
-            kPortIndexInput, OMX_VIDEO_CodingUnused,
-            colorFormat), (status_t)OK);
-
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexInput;
-
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    def.nBufferSize = getFrameSize(colorFormat,
-            stride > 0? stride: -stride, sliceHeight);
-
-    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
-
-    video_def->nFrameWidth = width;
-    video_def->nFrameHeight = height;
-    video_def->nStride = stride;
-    video_def->nSliceHeight = sliceHeight;
-    video_def->xFramerate = (frameRate << 16);  // Q16 format
-    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
-    video_def->eColorFormat = colorFormat;
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    //////////////////////// Output port /////////////////////////
-    CHECK_EQ(setVideoPortFormatType(
-            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
-            (status_t)OK);
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexOutput;
-
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
-    CHECK_EQ(err, (status_t)OK);
-    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
-
-    video_def->nFrameWidth = width;
-    video_def->nFrameHeight = height;
-    video_def->xFramerate = 0;      // No need for output port
-    video_def->nBitrate = bitRate;  // Q16 format
-    video_def->eCompressionFormat = compressionFormat;
-    video_def->eColorFormat = OMX_COLOR_FormatUnused;
-    if (mQuirks & kRequiresLargerEncoderOutputBuffer) {
-        // Increases the output buffer size
-        def.nBufferSize = ((def.nBufferSize * 3) >> 1);
-    }
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    /////////////////// Codec-specific ////////////////////////
-    switch (compressionFormat) {
-        case OMX_VIDEO_CodingMPEG4:
-        {
-            CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK);
-            break;
-        }
-
-        case OMX_VIDEO_CodingH263:
-            CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK);
-            break;
-
-        case OMX_VIDEO_CodingAVC:
-        {
-            CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK);
-            break;
-        }
-
-        default:
-            CHECK(!"Support for this compressionFormat to be implemented.");
-            break;
-    }
-}
-
-static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
-    if (iFramesInterval < 0) {
-        return 0xFFFFFFFF;
-    } else if (iFramesInterval == 0) {
-        return 0;
-    }
-    OMX_U32 ret = frameRate * iFramesInterval - 1;
-    return ret;
-}
-
-status_t OMXCodec::setupErrorCorrectionParameters() {
-    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
-    InitOMXParams(&errorCorrectionType);
-    errorCorrectionType.nPortIndex = kPortIndexOutput;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoErrorCorrection,
-            &errorCorrectionType, sizeof(errorCorrectionType));
-    if (err != OK) {
-        ALOGW("Error correction param query is not supported");
-        return OK;  // Optional feature. Ignore this failure
-    }
-
-    errorCorrectionType.bEnableHEC = OMX_FALSE;
-    errorCorrectionType.bEnableResync = OMX_TRUE;
-    errorCorrectionType.nResynchMarkerSpacing = 256;
-    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
-    errorCorrectionType.bEnableRVLC = OMX_FALSE;
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoErrorCorrection,
-            &errorCorrectionType, sizeof(errorCorrectionType));
-    if (err != OK) {
-        ALOGW("Error correction param configuration is not supported");
-    }
-
-    // Optional feature. Ignore the failure.
-    return OK;
-}
-
-status_t OMXCodec::setupBitRate(int32_t bitRate) {
-    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
-    InitOMXParams(&bitrateType);
-    bitrateType.nPortIndex = kPortIndexOutput;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoBitrate,
-            &bitrateType, sizeof(bitrateType));
-    CHECK_EQ(err, (status_t)OK);
-
-    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
-    bitrateType.nTargetBitrate = bitRate;
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoBitrate,
-            &bitrateType, sizeof(bitrateType));
-    CHECK_EQ(err, (status_t)OK);
-    return OK;
-}
-
-status_t OMXCodec::getVideoProfileLevel(
-        const sp<MetaData>& meta,
-        const CodecProfileLevel& defaultProfileLevel,
-        CodecProfileLevel &profileLevel) {
-    CODEC_LOGV("Default profile: %u, level #x%x",
-            defaultProfileLevel.mProfile, defaultProfileLevel.mLevel);
-
-    // Are the default profile and level overwriten?
-    int32_t profile, level;
-    if (!meta->findInt32(kKeyVideoProfile, &profile)) {
-        profile = defaultProfileLevel.mProfile;
-    }
-    if (!meta->findInt32(kKeyVideoLevel, &level)) {
-        level = defaultProfileLevel.mLevel;
-    }
-    CODEC_LOGV("Target profile: %d, level: %d", profile, level);
-
-    // Are the target profile and level supported by the encoder?
-    OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
-    InitOMXParams(&param);
-    param.nPortIndex = kPortIndexOutput;
-    for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
-        status_t err = mOMX->getParameter(
-                mNode, OMX_IndexParamVideoProfileLevelQuerySupported,
-                &param, sizeof(param));
-
-        if (err != OK) break;
-
-        int32_t supportedProfile = static_cast<int32_t>(param.eProfile);
-        int32_t supportedLevel = static_cast<int32_t>(param.eLevel);
-        CODEC_LOGV("Supported profile: %d, level %d",
-            supportedProfile, supportedLevel);
-
-        if (profile == supportedProfile &&
-            level <= supportedLevel) {
-            // We can further check whether the level is a valid
-            // value; but we will leave that to the omx encoder component
-            // via OMX_SetParameter call.
-            profileLevel.mProfile = profile;
-            profileLevel.mLevel = level;
-            return OK;
-        }
-    }
-
-    CODEC_LOGE("Target profile (%d) and level (%d) is not supported",
-            profile, level);
-    return BAD_VALUE;
-}
-
-status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
-    int32_t iFramesInterval, frameRate, bitRate;
-    bool success = meta->findInt32(kKeyBitRate, &bitRate);
-    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
-    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
-    CHECK(success);
-    OMX_VIDEO_PARAM_H263TYPE h263type;
-    InitOMXParams(&h263type);
-    h263type.nPortIndex = kPortIndexOutput;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
-    CHECK_EQ(err, (status_t)OK);
-
-    h263type.nAllowedPictureTypes =
-        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
-
-    h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
-    if (h263type.nPFrames == 0) {
-        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
-    }
-    h263type.nBFrames = 0;
-
-    // Check profile and level parameters
-    CodecProfileLevel defaultProfileLevel, profileLevel;
-    defaultProfileLevel.mProfile = h263type.eProfile;
-    defaultProfileLevel.mLevel = h263type.eLevel;
-    err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
-    if (err != OK) return err;
-    h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile);
-    h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel);
-
-    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
-    h263type.bForceRoundingTypeToZero = OMX_FALSE;
-    h263type.nPictureHeaderRepetition = 0;
-    h263type.nGOBHeaderInterval = 0;
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
-    CHECK_EQ(err, (status_t)OK);
-
-    CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
-    CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
-
-    return OK;
-}
-
-status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
-    int32_t iFramesInterval, frameRate, bitRate;
-    bool success = meta->findInt32(kKeyBitRate, &bitRate);
-    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
-    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
-    CHECK(success);
-    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
-    InitOMXParams(&mpeg4type);
-    mpeg4type.nPortIndex = kPortIndexOutput;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
-    CHECK_EQ(err, (status_t)OK);
-
-    mpeg4type.nSliceHeaderSpacing = 0;
-    mpeg4type.bSVH = OMX_FALSE;
-    mpeg4type.bGov = OMX_FALSE;
-
-    mpeg4type.nAllowedPictureTypes =
-        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
-
-    mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
-    if (mpeg4type.nPFrames == 0) {
-        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
-    }
-    mpeg4type.nBFrames = 0;
-    mpeg4type.nIDCVLCThreshold = 0;
-    mpeg4type.bACPred = OMX_TRUE;
-    mpeg4type.nMaxPacketSize = 256;
-    mpeg4type.nTimeIncRes = 1000;
-    mpeg4type.nHeaderExtension = 0;
-    mpeg4type.bReversibleVLC = OMX_FALSE;
-
-    // Check profile and level parameters
-    CodecProfileLevel defaultProfileLevel, profileLevel;
-    defaultProfileLevel.mProfile = mpeg4type.eProfile;
-    defaultProfileLevel.mLevel = mpeg4type.eLevel;
-    err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
-    if (err != OK) return err;
-    mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile);
-    mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel);
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
-    CHECK_EQ(err, (status_t)OK);
-
-    CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
-    CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK);
-
-    return OK;
-}
-
-status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
-    int32_t iFramesInterval, frameRate, bitRate;
-    bool success = meta->findInt32(kKeyBitRate, &bitRate);
-    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
-    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
-    CHECK(success);
-
-    OMX_VIDEO_PARAM_AVCTYPE h264type;
-    InitOMXParams(&h264type);
-    h264type.nPortIndex = kPortIndexOutput;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
-    CHECK_EQ(err, (status_t)OK);
-
-    h264type.nAllowedPictureTypes =
-        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
-
-    // Check profile and level parameters
-    CodecProfileLevel defaultProfileLevel, profileLevel;
-    defaultProfileLevel.mProfile = h264type.eProfile;
-    defaultProfileLevel.mLevel = h264type.eLevel;
-    err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
-    if (err != OK) return err;
-    h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile);
-    h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel);
-
-    // XXX
-    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
-        ALOGW("Use baseline profile instead of %d for AVC recording",
-            h264type.eProfile);
-        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
-    }
-
-    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
-        h264type.nSliceHeaderSpacing = 0;
-        h264type.bUseHadamard = OMX_TRUE;
-        h264type.nRefFrames = 1;
-        h264type.nBFrames = 0;
-        h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
-        if (h264type.nPFrames == 0) {
-            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
-        }
-        h264type.nRefIdx10ActiveMinus1 = 0;
-        h264type.nRefIdx11ActiveMinus1 = 0;
-        h264type.bEntropyCodingCABAC = OMX_FALSE;
-        h264type.bWeightedPPrediction = OMX_FALSE;
-        h264type.bconstIpred = OMX_FALSE;
-        h264type.bDirect8x8Inference = OMX_FALSE;
-        h264type.bDirectSpatialTemporal = OMX_FALSE;
-        h264type.nCabacInitIdc = 0;
-    }
-
-    if (h264type.nBFrames != 0) {
-        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
-    }
-
-    h264type.bEnableUEP = OMX_FALSE;
-    h264type.bEnableFMO = OMX_FALSE;
-    h264type.bEnableASO = OMX_FALSE;
-    h264type.bEnableRS = OMX_FALSE;
-    h264type.bFrameMBsOnly = OMX_TRUE;
-    h264type.bMBAFF = OMX_FALSE;
-    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
-    CHECK_EQ(err, (status_t)OK);
-
-    CHECK_EQ(setupBitRate(bitRate), (status_t)OK);
-
-    return OK;
-}
-
-status_t OMXCodec::setVideoOutputFormat(
-        const char *mime, const sp<MetaData>& meta) {
-
-    int32_t width, height;
-    bool success = meta->findInt32(kKeyWidth, &width);
-    success = success && meta->findInt32(kKeyHeight, &height);
-    CHECK(success);
-
-    CODEC_LOGV("setVideoOutputFormat width=%d, height=%d", width, height);
-
-    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
-    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
-        compressionFormat = OMX_VIDEO_CodingAVC;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
-        compressionFormat = OMX_VIDEO_CodingMPEG4;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
-        compressionFormat = OMX_VIDEO_CodingHEVC;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
-        compressionFormat = OMX_VIDEO_CodingH263;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP8, mime)) {
-        compressionFormat = OMX_VIDEO_CodingVP8;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP9, mime)) {
-        compressionFormat = OMX_VIDEO_CodingVP9;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
-        compressionFormat = OMX_VIDEO_CodingMPEG2;
-    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, mime)) {
-        compressionFormat = OMX_VIDEO_CodingDolbyVision;
-    } else {
-        ALOGE("Not a supported video mime type: %s", mime);
-        CHECK(!"Should not be here. Not a supported video mime type.");
-    }
-
-    status_t err = setVideoPortFormatType(
-            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
-
-    if (err != OK) {
-        return err;
-    }
-
-#if 1
-    {
-        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
-        InitOMXParams(&format);
-        format.nPortIndex = kPortIndexOutput;
-        format.nIndex = 0;
-
-        status_t err = mOMX->getParameter(
-                mNode, OMX_IndexParamVideoPortFormat,
-                &format, sizeof(format));
-        CHECK_EQ(err, (status_t)OK);
-        CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
-
-        int32_t colorFormat;
-        if (meta->findInt32(kKeyColorFormat, &colorFormat)
-                && colorFormat != OMX_COLOR_FormatUnused
-                && colorFormat != format.eColorFormat) {
-
-            while (OMX_ErrorNoMore != err) {
-                format.nIndex++;
-                err = mOMX->getParameter(
-                        mNode, OMX_IndexParamVideoPortFormat,
-                            &format, sizeof(format));
-                if (format.eColorFormat == colorFormat) {
-                    break;
-                }
-            }
-            if (format.eColorFormat != colorFormat) {
-                CODEC_LOGE("Color format %d is not supported", colorFormat);
-                return ERROR_UNSUPPORTED;
-            }
-        }
-
-        err = mOMX->setParameter(
-                mNode, OMX_IndexParamVideoPortFormat,
-                &format, sizeof(format));
-
-        if (err != OK) {
-            return err;
-        }
-    }
-#endif
-
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexInput;
-
-    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
-
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
-    CHECK_EQ(err, (status_t)OK);
-
-#if 1
-    // XXX Need a (much) better heuristic to compute input buffer sizes.
-    const size_t X = 64 * 1024;
-    if (def.nBufferSize < X) {
-        def.nBufferSize = X;
-    }
-#endif
-
-    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
-
-    video_def->nFrameWidth = width;
-    video_def->nFrameHeight = height;
-
-    video_def->eCompressionFormat = compressionFormat;
-    video_def->eColorFormat = OMX_COLOR_FormatUnused;
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
-    if (err != OK) {
-        return err;
-    }
-
-    ////////////////////////////////////////////////////////////////////////////
-
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexOutput;
-
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
-
-#if 0
-    def.nBufferSize =
-        (((width + 15) & -16) * ((height + 15) & -16) * 3) / 2;  // YUV420
-#endif
-
-    video_def->nFrameWidth = width;
-    video_def->nFrameHeight = height;
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
-    return err;
-}
-
-OMXCodec::OMXCodec(
-        const sp<IOMX> &omx, IOMX::node_id node,
-        uint32_t quirks, uint32_t flags,
-        bool isEncoder,
-        const char *mime,
-        const char *componentName,
-        const sp<IMediaSource> &source,
-        const sp<ANativeWindow> &nativeWindow)
-    : mOMX(omx),
-      mOMXLivesLocally(omx->livesLocally(node, getpid())),
-      mNode(node),
-      mQuirks(quirks),
-      mFlags(flags),
-      mIsEncoder(isEncoder),
-      mIsVideo(!strncasecmp("video/", mime, 6)),
-      mMIME(strdup(mime)),
-      mComponentName(strdup(componentName)),
-      mSource(source),
-      mCodecSpecificDataIndex(0),
-      mState(LOADED),
-      mInitialBufferSubmit(true),
-      mSignalledEOS(false),
-      mNoMoreOutputData(false),
-      mOutputPortSettingsHaveChanged(false),
-      mSeekTimeUs(-1),
-      mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
-      mTargetTimeUs(-1),
-      mOutputPortSettingsChangedPending(false),
-      mSkipCutBuffer(NULL),
-      mLeftOverBuffer(NULL),
-      mPaused(false),
-      mNativeWindow(
-              (!strncmp(componentName, "OMX.google.", 11))
-                        ? NULL : nativeWindow) {
-    mPortStatus[kPortIndexInput] = ENABLED;
-    mPortStatus[kPortIndexOutput] = ENABLED;
-
-    setComponentRole();
-}
-
-// static
-void OMXCodec::setComponentRole(
-        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
-        const char *mime) {
-    struct MimeToRole {
-        const char *mime;
-        const char *decoderRole;
-        const char *encoderRole;
-    };
-
-    static const MimeToRole kMimeToRole[] = {
-        { MEDIA_MIMETYPE_AUDIO_MPEG,
-            "audio_decoder.mp3", "audio_encoder.mp3" },
-        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
-            "audio_decoder.mp1", "audio_encoder.mp1" },
-        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
-            "audio_decoder.mp2", "audio_encoder.mp2" },
-        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
-            "audio_decoder.amrnb", "audio_encoder.amrnb" },
-        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
-            "audio_decoder.amrwb", "audio_encoder.amrwb" },
-        { MEDIA_MIMETYPE_AUDIO_AAC,
-            "audio_decoder.aac", "audio_encoder.aac" },
-        { MEDIA_MIMETYPE_AUDIO_VORBIS,
-            "audio_decoder.vorbis", "audio_encoder.vorbis" },
-        { MEDIA_MIMETYPE_AUDIO_OPUS,
-            "audio_decoder.opus", "audio_encoder.opus" },
-        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
-            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
-        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
-            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
-        { MEDIA_MIMETYPE_VIDEO_AVC,
-            "video_decoder.avc", "video_encoder.avc" },
-        { MEDIA_MIMETYPE_VIDEO_HEVC,
-            "video_decoder.hevc", "video_encoder.hevc" },
-        { MEDIA_MIMETYPE_VIDEO_MPEG4,
-            "video_decoder.mpeg4", "video_encoder.mpeg4" },
-        { MEDIA_MIMETYPE_VIDEO_H263,
-            "video_decoder.h263", "video_encoder.h263" },
-        { MEDIA_MIMETYPE_VIDEO_VP8,
-            "video_decoder.vp8", "video_encoder.vp8" },
-        { MEDIA_MIMETYPE_VIDEO_VP9,
-            "video_decoder.vp9", "video_encoder.vp9" },
-        { MEDIA_MIMETYPE_AUDIO_RAW,
-            "audio_decoder.raw", "audio_encoder.raw" },
-        { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
-            "video_decoder.dolby-vision", "video_encoder.dolby-vision" },
-        { MEDIA_MIMETYPE_AUDIO_FLAC,
-            "audio_decoder.flac", "audio_encoder.flac" },
-        { MEDIA_MIMETYPE_AUDIO_MSGSM,
-            "audio_decoder.gsm", "audio_encoder.gsm" },
-        { MEDIA_MIMETYPE_VIDEO_MPEG2,
-            "video_decoder.mpeg2", "video_encoder.mpeg2" },
-        { MEDIA_MIMETYPE_AUDIO_AC3,
-            "audio_decoder.ac3", "audio_encoder.ac3" },
-    };
-
-    static const size_t kNumMimeToRole =
-        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
-
-    size_t i;
-    for (i = 0; i < kNumMimeToRole; ++i) {
-        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
-            break;
-        }
-    }
-
-    if (i == kNumMimeToRole) {
-        return;
-    }
-
-    const char *role =
-        isEncoder ? kMimeToRole[i].encoderRole
-                  : kMimeToRole[i].decoderRole;
-
-    if (role != NULL) {
-        OMX_PARAM_COMPONENTROLETYPE roleParams;
-        InitOMXParams(&roleParams);
-
-        strncpy((char *)roleParams.cRole,
-                role, OMX_MAX_STRINGNAME_SIZE - 1);
-
-        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
-
-        status_t err = omx->setParameter(
-                node, OMX_IndexParamStandardComponentRole,
-                &roleParams, sizeof(roleParams));
-
-        if (err != OK) {
-            ALOGW("Failed to set standard component role '%s'.", role);
-        }
-    }
-}
-
-void OMXCodec::setComponentRole() {
-    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
-}
-
-OMXCodec::~OMXCodec() {
-    mSource.clear();
-
-    CHECK(mState == LOADED || mState == ERROR || mState == LOADED_TO_IDLE);
-
-    status_t err = mOMX->freeNode(mNode);
-    CHECK_EQ(err, (status_t)OK);
-
-    mNode = 0;
-    setState(DEAD);
-
-    clearCodecSpecificData();
-
-    free(mComponentName);
-    mComponentName = NULL;
-
-    free(mMIME);
-    mMIME = NULL;
-}
-
-status_t OMXCodec::init() {
-    // mLock is held.
-
-    CHECK_EQ((int)mState, (int)LOADED);
-
-    status_t err;
-    if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
-        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
-        CHECK_EQ(err, (status_t)OK);
-        setState(LOADED_TO_IDLE);
-    }
-
-    err = allocateBuffers();
-    if (err != (status_t)OK) {
-        return err;
-    }
-
-    if (mQuirks & kRequiresLoadedToIdleAfterAllocation) {
-        err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
-        CHECK_EQ(err, (status_t)OK);
-
-        setState(LOADED_TO_IDLE);
-    }
-
-    while (mState != EXECUTING && mState != ERROR) {
-        mAsyncCompletion.wait(mLock);
-    }
-
-    return mState == ERROR ? UNKNOWN_ERROR : OK;
-}
-
-// static
-bool OMXCodec::isIntermediateState(State state) {
-    return state == LOADED_TO_IDLE
-        || state == IDLE_TO_EXECUTING
-        || state == EXECUTING_TO_IDLE
-        || state == IDLE_TO_LOADED
-        || state == RECONFIGURING;
-}
-
-status_t OMXCodec::allocateBuffers() {
-    status_t err = allocateBuffersOnPort(kPortIndexInput);
-
-    if (err != OK) {
-        return err;
-    }
-
-    return allocateBuffersOnPort(kPortIndexOutput);
-}
-
-status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
-    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
-        return allocateOutputBuffersFromNativeWindow();
-    }
-
-    if ((mFlags & kEnableGrallocUsageProtected) && portIndex == kPortIndexOutput) {
-        ALOGE("protected output buffers must be stent to an ANativeWindow");
-        return PERMISSION_DENIED;
-    }
-
-    status_t err = OK;
-    if ((mFlags & kStoreMetaDataInVideoBuffers)
-            && portIndex == kPortIndexInput) {
-        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
-        if (err != OK) {
-            ALOGE("Storing meta data in video buffers is not supported");
-            return err;
-        }
-    }
-
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = portIndex;
-
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
-    if (err != OK) {
-        return err;
-    }
-
-    CODEC_LOGV("allocating %u buffers of size %u on %s port",
-            def.nBufferCountActual, def.nBufferSize,
-            portIndex == kPortIndexInput ? "input" : "output");
-
-    if (def.nBufferSize != 0 && def.nBufferCountActual > SIZE_MAX / def.nBufferSize) {
-        return BAD_VALUE;
-    }
-    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
-    mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
-
-    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
-        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
-        CHECK(mem.get() != NULL);
-
-        BufferInfo info;
-        info.mData = NULL;
-        info.mSize = def.nBufferSize;
-
-        IOMX::buffer_id buffer;
-        if (portIndex == kPortIndexInput
-                && ((mQuirks & kRequiresAllocateBufferOnInputPorts)
-                    || (mFlags & kUseSecureInputBuffers))) {
-            if (mOMXLivesLocally) {
-                mem.clear();
-
-                err = mOMX->allocateBuffer(
-                        mNode, portIndex, def.nBufferSize, &buffer,
-                        &info.mData);
-            } else {
-                err = mOMX->allocateBufferWithBackup(
-                        mNode, portIndex, mem, &buffer, mem->size());
-            }
-        } else if (portIndex == kPortIndexOutput
-                && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
-            if (mOMXLivesLocally) {
-                mem.clear();
-
-                err = mOMX->allocateBuffer(
-                        mNode, portIndex, def.nBufferSize, &buffer,
-                        &info.mData);
-            } else {
-                err = mOMX->allocateBufferWithBackup(
-                        mNode, portIndex, mem, &buffer, mem->size());
-            }
-        } else {
-            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer, mem->size());
-        }
-
-        if (err != OK) {
-            ALOGE("allocate_buffer_with_backup failed");
-            return err;
-        }
-
-        if (mem != NULL) {
-            info.mData = mem->pointer();
-        }
-
-        info.mBuffer = buffer;
-        info.mStatus = OWNED_BY_US;
-        info.mMem = mem;
-        info.mMediaBuffer = NULL;
-
-        if (portIndex == kPortIndexOutput) {
-            // Fail deferred MediaBuffer creation until FILL_BUFFER_DONE;
-            // this legacy mode is no longer supported.
-            LOG_ALWAYS_FATAL_IF((mOMXLivesLocally
-                    && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
-                    && (mQuirks & kDefersOutputBufferAllocation)),
-                    "allocateBuffersOnPort cannot defer buffer allocation");
-
-            info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
-            info.mMediaBuffer->setObserver(this);
-        }
-
-        mPortBuffers[portIndex].push(info);
-
-        CODEC_LOGV("allocated buffer %u on %s port", buffer,
-             portIndex == kPortIndexInput ? "input" : "output");
-    }
-
-    if (portIndex == kPortIndexOutput) {
-
-        sp<MetaData> meta = mSource->getFormat();
-        int32_t delay = 0;
-        if (!meta->findInt32(kKeyEncoderDelay, &delay)) {
-            delay = 0;
-        }
-        int32_t padding = 0;
-        if (!meta->findInt32(kKeyEncoderPadding, &padding)) {
-            padding = 0;
-        }
-        int32_t numchannels = 0;
-        if (delay + padding) {
-            if (mOutputFormat->findInt32(kKeyChannelCount, &numchannels)) {
-                if (mSkipCutBuffer != NULL) {
-                    size_t prevbuffersize = mSkipCutBuffer->size();
-                    if (prevbuffersize != 0) {
-                        ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbuffersize);
-                    }
-                }
-                mSkipCutBuffer = new SkipCutBuffer(delay, padding, numchannels);
-            }
-        }
-    }
-
-    // dumpPortStatus(portIndex);
-
-    if (portIndex == kPortIndexInput && (mFlags & kUseSecureInputBuffers)) {
-        Vector<MediaBuffer *> buffers;
-        for (size_t i = 0; i < def.nBufferCountActual; ++i) {
-            const BufferInfo &info = mPortBuffers[kPortIndexInput].itemAt(i);
-
-            MediaBuffer *mbuf = new MediaBuffer(info.mData, info.mSize);
-            buffers.push(mbuf);
-        }
-
-        status_t err = mSource->setBuffers(buffers);
-
-        if (err != OK) {
-            for (size_t i = 0; i < def.nBufferCountActual; ++i) {
-                buffers.editItemAt(i)->release();
-            }
-            buffers.clear();
-
-            CODEC_LOGE(
-                    "Codec requested to use secure input buffers but "
-                    "upstream source didn't support that.");
-
-            return err;
-        }
-    }
-
-    return OK;
-}
-
-status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
-    // Get the number of buffers needed.
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexOutput;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    if (err != OK) {
-        CODEC_LOGE("getParameter failed: %d", err);
-        return err;
-    }
-
-    sp<MetaData> meta = mSource->getFormat();
-
-    int32_t rotationDegrees;
-    if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
-        rotationDegrees = 0;
-    }
-
-    // Set up the native window.
-    OMX_U32 usage = 0;
-    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
-    if (err != 0) {
-        ALOGW("querying usage flags from OMX IL component failed: %d", err);
-        // XXX: Currently this error is logged, but not fatal.
-        usage = 0;
-    }
-
-    if (mFlags & kEnableGrallocUsageProtected) {
-        usage |= GRALLOC_USAGE_PROTECTED;
-    }
-
-    err = setNativeWindowSizeFormatAndUsage(
-            mNativeWindow.get(),
-            def.format.video.nFrameWidth,
-            def.format.video.nFrameHeight,
-            def.format.video.eColorFormat,
-            rotationDegrees,
-            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
-    if (err != 0) {
-        return err;
-    }
-
-    int minUndequeuedBufs = 0;
-    err = mNativeWindow->query(mNativeWindow.get(),
-            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
-    if (err != 0) {
-        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
-                strerror(-err), -err);
-        return err;
-    }
-    // FIXME: assume that surface is controlled by app (native window
-    // returns the number for the case when surface is not controlled by app)
-    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
-    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
-
-    // Use conservative allocation while also trying to reduce starvation
-    //
-    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
-    //    minimum needed for the consumer to be able to work
-    // 2. try to allocate two (2) additional buffers to reduce starvation from
-    //    the consumer
-    //    plus an extra buffer to account for incorrect minUndequeuedBufs
-    CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1",
-            def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs);
-
-    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
-        OMX_U32 newBufferCount =
-            def.nBufferCountMin + minUndequeuedBufs + extraBuffers;
-        def.nBufferCountActual = newBufferCount;
-        err = mOMX->setParameter(
-                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
-        if (err == OK) {
-            minUndequeuedBufs += extraBuffers;
-            break;
-        }
-
-        CODEC_LOGW("setting nBufferCountActual to %u failed: %d",
-                newBufferCount, err);
-        /* exit condition */
-        if (extraBuffers == 0) {
-            return err;
-        }
-    }
-    CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1",
-            def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs);
-
-    err = native_window_set_buffer_count(
-            mNativeWindow.get(), def.nBufferCountActual);
-    if (err != 0) {
-        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
-                -err);
-        return err;
-    }
-
-    CODEC_LOGV("allocating %u buffers from a native window of size %u on "
-            "output port", def.nBufferCountActual, def.nBufferSize);
-
-    // Dequeue buffers and send them to OMX
-    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
-        ANativeWindowBuffer* buf;
-        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
-        if (err != 0) {
-            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
-            break;
-        }
-
-        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
-        BufferInfo info;
-        info.mData = NULL;
-        info.mSize = def.nBufferSize;
-        info.mStatus = OWNED_BY_US;
-        info.mMem = NULL;
-        info.mMediaBuffer = new MediaBuffer(graphicBuffer);
-        info.mMediaBuffer->setObserver(this);
-        mPortBuffers[kPortIndexOutput].push(info);
-
-        IOMX::buffer_id bufferId;
-        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
-                &bufferId);
-        if (err != 0) {
-            CODEC_LOGE("registering GraphicBuffer with OMX IL component "
-                    "failed: %d", err);
-            break;
-        }
-
-        mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId;
-
-        CODEC_LOGV("registered graphic buffer with ID %u (pointer = %p)",
-                bufferId, graphicBuffer.get());
-    }
-
-    OMX_U32 cancelStart;
-    OMX_U32 cancelEnd;
-    if (err != 0) {
-        // If an error occurred while dequeuing we need to cancel any buffers
-        // that were dequeued.
-        cancelStart = 0;
-        cancelEnd = mPortBuffers[kPortIndexOutput].size();
-    } else {
-        // Return the last two buffers to the native window.
-        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
-        cancelEnd = def.nBufferCountActual;
-    }
-
-    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
-        BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(i);
-        cancelBufferToNativeWindow(info);
-    }
-
-    return err;
-}
-
-status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) {
-    CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
-    CODEC_LOGV("Calling cancelBuffer on buffer %u", info->mBuffer);
-    int err = mNativeWindow->cancelBuffer(
-        mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1);
-    if (err != 0) {
-      CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err);
-
-      setState(ERROR);
-      return err;
-    }
-    info->mStatus = OWNED_BY_NATIVE_WINDOW;
-    return OK;
-}
-
-OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
-    // Dequeue the next buffer from the native window.
-    ANativeWindowBuffer* buf;
-    int err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
-    if (err != 0) {
-      CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
-
-      setState(ERROR);
-      return 0;
-    }
-
-    // Determine which buffer we just dequeued.
-    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
-    BufferInfo *bufInfo = 0;
-    for (size_t i = 0; i < buffers->size(); i++) {
-      sp<GraphicBuffer> graphicBuffer = buffers->itemAt(i).
-          mMediaBuffer->graphicBuffer();
-      if (graphicBuffer->handle == buf->handle) {
-        bufInfo = &buffers->editItemAt(i);
-        break;
-      }
-    }
-
-    if (bufInfo == 0) {
-        CODEC_LOGE("dequeued unrecognized buffer: %p", buf);
-
-        setState(ERROR);
-        return 0;
-    }
-
-    // The native window no longer owns the buffer.
-    CHECK_EQ((int)bufInfo->mStatus, (int)OWNED_BY_NATIVE_WINDOW);
-    bufInfo->mStatus = OWNED_BY_US;
-
-    return bufInfo;
-}
-
-int64_t OMXCodec::getDecodingTimeUs() {
-    CHECK(mIsEncoder && mIsVideo);
-
-    if (mDecodingTimeList.empty()) {
-        CHECK(mSignalledEOS || mNoMoreOutputData);
-        // No corresponding input frame available.
-        // This could happen when EOS is reached.
-        return 0;
-    }
-
-    List<int64_t>::iterator it = mDecodingTimeList.begin();
-    int64_t timeUs = *it;
-    mDecodingTimeList.erase(it);
-    return timeUs;
-}
-
-void OMXCodec::on_message(const omx_message &msg) {
-    if (mState == ERROR) {
-        /*
-         * only drop EVENT messages, EBD and FBD are still
-         * processed for bookkeeping purposes
-         */
-        if (msg.type == omx_message::EVENT) {
-            ALOGW("Dropping OMX EVENT message - we're in ERROR state.");
-            return;
-        }
-    }
-
-    switch (msg.type) {
-        case omx_message::EVENT:
-        {
-            onEvent(
-                 msg.u.event_data.event, msg.u.event_data.data1,
-                 msg.u.event_data.data2);
-
-            break;
-        }
-
-        case omx_message::EMPTY_BUFFER_DONE:
-        {
-            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
-
-            CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %u)", buffer);
-
-            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
-            size_t i = 0;
-            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
-                ++i;
-            }
-
-            CHECK(i < buffers->size());
-            if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) {
-                ALOGW("We already own input buffer %u, yet received "
-                     "an EMPTY_BUFFER_DONE.", buffer);
-            }
-
-            BufferInfo* info = &buffers->editItemAt(i);
-            info->mStatus = OWNED_BY_US;
-
-            // Buffer could not be released until empty buffer done is called.
-            if (info->mMediaBuffer != NULL) {
-                info->mMediaBuffer->release();
-                info->mMediaBuffer = NULL;
-            }
-
-            if (mPortStatus[kPortIndexInput] == DISABLING) {
-                CODEC_LOGV("Port is disabled, freeing buffer %u", buffer);
-
-                status_t err = freeBuffer(kPortIndexInput, i);
-                CHECK_EQ(err, (status_t)OK);
-            } else if (mState != ERROR
-                    && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
-                CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED);
-
-                if (mFlags & kUseSecureInputBuffers) {
-                    drainAnyInputBuffer();
-                } else {
-                    drainInputBuffer(&buffers->editItemAt(i));
-                }
-            }
-            break;
-        }
-
-        case omx_message::FILL_BUFFER_DONE:
-        {
-            IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
-            OMX_U32 flags = msg.u.extended_buffer_data.flags;
-
-            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %u, size: %u, flags: 0x%08x, timestamp: %lld us (%.2f secs))",
-                 buffer,
-                 msg.u.extended_buffer_data.range_length,
-                 flags,
-                 msg.u.extended_buffer_data.timestamp,
-                 msg.u.extended_buffer_data.timestamp / 1E6);
-
-            Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
-            size_t i = 0;
-            while (i < buffers->size() && (*buffers)[i].mBuffer != buffer) {
-                ++i;
-            }
-
-            CHECK(i < buffers->size());
-            BufferInfo *info = &buffers->editItemAt(i);
-
-            if (info->mStatus != OWNED_BY_COMPONENT) {
-                ALOGW("We already own output buffer %u, yet received "
-                     "a FILL_BUFFER_DONE.", buffer);
-            }
-
-            info->mStatus = OWNED_BY_US;
-
-            if (mPortStatus[kPortIndexOutput] == DISABLING) {
-                CODEC_LOGV("Port is disabled, freeing buffer %u", buffer);
-
-                status_t err = freeBuffer(kPortIndexOutput, i);
-                CHECK_EQ(err, (status_t)OK);
-
-#if 0
-            } else if (mPortStatus[kPortIndexOutput] == ENABLED
-                       && (flags & OMX_BUFFERFLAG_EOS)) {
-                CODEC_LOGV("No more output data.");
-                mNoMoreOutputData = true;
-                mBufferFilled.signal();
-#endif
-            } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
-                CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
-
-                MediaBuffer *buffer = info->mMediaBuffer;
-                bool isGraphicBuffer = buffer->graphicBuffer() != NULL;
-
-                if (!isGraphicBuffer
-                    && msg.u.extended_buffer_data.range_offset
-                        + msg.u.extended_buffer_data.range_length
-                            > buffer->size()) {
-                    CODEC_LOGE(
-                            "Codec lied about its buffer size requirements, "
-                            "sending a buffer larger than the originally "
-                            "advertised size in FILL_BUFFER_DONE!");
-                }
-                buffer->set_range(
-                        msg.u.extended_buffer_data.range_offset,
-                        msg.u.extended_buffer_data.range_length);
-
-                buffer->meta_data()->clear();
-
-                buffer->meta_data()->setInt64(
-                        kKeyTime, msg.u.extended_buffer_data.timestamp);
-
-                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);
-                }
-
-                buffer->meta_data()->setInt32(
-                        kKeyBufferID,
-                        msg.u.extended_buffer_data.buffer);
-
-                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
-                    CODEC_LOGV("No more output data.");
-                    mNoMoreOutputData = true;
-                }
-
-                if (mIsEncoder && mIsVideo) {
-                    int64_t decodingTimeUs = isCodecSpecific? 0: getDecodingTimeUs();
-                    buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
-                }
-
-                if (mTargetTimeUs >= 0) {
-                    CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs);
-
-                    if (msg.u.extended_buffer_data.timestamp < mTargetTimeUs) {
-                        CODEC_LOGV(
-                                "skipping output buffer at timestamp %lld us",
-                                msg.u.extended_buffer_data.timestamp);
-
-                        fillOutputBuffer(info);
-                        break;
-                    }
-
-                    CODEC_LOGV(
-                            "returning output buffer at target timestamp "
-                            "%lld us",
-                            msg.u.extended_buffer_data.timestamp);
-
-                    mTargetTimeUs = -1;
-                }
-
-                mFilledBuffers.push_back(i);
-                mBufferFilled.signal();
-                if (mIsEncoder) {
-                    sched_yield();
-                }
-            }
-
-            break;
-        }
-
-        default:
-        {
-            CHECK(!"should not be here.");
-            break;
-        }
-    }
-}
-
-// Has the format changed in any way that the client would have to be aware of?
-static bool formatHasNotablyChanged(
-        const sp<MetaData> &from, const sp<MetaData> &to) {
-    if (from.get() == NULL && to.get() == NULL) {
-        return false;
-    }
-
-    if ((from.get() == NULL && to.get() != NULL)
-        || (from.get() != NULL && to.get() == NULL)) {
-        return true;
-    }
-
-    const char *mime_from, *mime_to;
-    CHECK(from->findCString(kKeyMIMEType, &mime_from));
-    CHECK(to->findCString(kKeyMIMEType, &mime_to));
-
-    if (strcasecmp(mime_from, mime_to)) {
-        return true;
-    }
-
-    if (!strcasecmp(mime_from, MEDIA_MIMETYPE_VIDEO_RAW)) {
-        int32_t colorFormat_from, colorFormat_to;
-        CHECK(from->findInt32(kKeyColorFormat, &colorFormat_from));
-        CHECK(to->findInt32(kKeyColorFormat, &colorFormat_to));
-
-        if (colorFormat_from != colorFormat_to) {
-            return true;
-        }
-
-        int32_t width_from, width_to;
-        CHECK(from->findInt32(kKeyWidth, &width_from));
-        CHECK(to->findInt32(kKeyWidth, &width_to));
-
-        if (width_from != width_to) {
-            return true;
-        }
-
-        int32_t height_from, height_to;
-        CHECK(from->findInt32(kKeyHeight, &height_from));
-        CHECK(to->findInt32(kKeyHeight, &height_to));
-
-        if (height_from != height_to) {
-            return true;
-        }
-
-        int32_t left_from, top_from, right_from, bottom_from;
-        CHECK(from->findRect(
-                    kKeyCropRect,
-                    &left_from, &top_from, &right_from, &bottom_from));
-
-        int32_t left_to, top_to, right_to, bottom_to;
-        CHECK(to->findRect(
-                    kKeyCropRect,
-                    &left_to, &top_to, &right_to, &bottom_to));
-
-        if (left_to != left_from || top_to != top_from
-                || right_to != right_from || bottom_to != bottom_from) {
-            return true;
-        }
-    } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) {
-        int32_t numChannels_from, numChannels_to;
-        CHECK(from->findInt32(kKeyChannelCount, &numChannels_from));
-        CHECK(to->findInt32(kKeyChannelCount, &numChannels_to));
-
-        if (numChannels_from != numChannels_to) {
-            return true;
-        }
-
-        int32_t sampleRate_from, sampleRate_to;
-        CHECK(from->findInt32(kKeySampleRate, &sampleRate_from));
-        CHECK(to->findInt32(kKeySampleRate, &sampleRate_to));
-
-        if (sampleRate_from != sampleRate_to) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
-    switch (event) {
-        case OMX_EventCmdComplete:
-        {
-            onCmdComplete((OMX_COMMANDTYPE)data1, data2);
-            break;
-        }
-
-        case OMX_EventError:
-        {
-            CODEC_LOGE("OMX_EventError(0x%08x, %u)", data1, data2);
-
-            setState(ERROR);
-            break;
-        }
-
-        case OMX_EventPortSettingsChanged:
-        {
-            CODEC_LOGV("OMX_EventPortSettingsChanged(port=%u, data2=0x%08x)",
-                       data1, data2);
-
-            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
-                onPortSettingsChanged(data1);
-            } else if (data1 == kPortIndexOutput &&
-                        (data2 == OMX_IndexConfigCommonOutputCrop ||
-                         data2 == OMX_IndexConfigCommonScale)) {
-
-                sp<MetaData> oldOutputFormat = mOutputFormat;
-                initOutputFormat(mSource->getFormat());
-
-                if (data2 == OMX_IndexConfigCommonOutputCrop &&
-                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
-                    mOutputPortSettingsHaveChanged = true;
-
-                } else if (data2 == OMX_IndexConfigCommonScale) {
-                    OMX_CONFIG_SCALEFACTORTYPE scale;
-                    InitOMXParams(&scale);
-                    scale.nPortIndex = kPortIndexOutput;
-
-                    // Change display dimension only when necessary.
-                    if (OK == mOMX->getConfig(
-                                        mNode,
-                                        OMX_IndexConfigCommonScale,
-                                        &scale, sizeof(scale))) {
-                        int32_t left, top, right, bottom;
-                        CHECK(mOutputFormat->findRect(kKeyCropRect,
-                                                      &left, &top,
-                                                      &right, &bottom));
-
-                        // The scale is in 16.16 format.
-                        // scale 1.0 = 0x010000. When there is no
-                        // need to change the display, skip it.
-                        ALOGV("Get OMX_IndexConfigScale: 0x%x/0x%x",
-                                scale.xWidth, scale.xHeight);
-
-                        if (scale.xWidth != 0x010000) {
-                            mOutputFormat->setInt32(kKeyDisplayWidth,
-                                    ((right - left +  1) * scale.xWidth)  >> 16);
-                            mOutputPortSettingsHaveChanged = true;
-                        }
-
-                        if (scale.xHeight != 0x010000) {
-                            mOutputFormat->setInt32(kKeyDisplayHeight,
-                                    ((bottom  - top + 1) * scale.xHeight) >> 16);
-                            mOutputPortSettingsHaveChanged = true;
-                        }
-                    }
-                }
-            }
-            break;
-        }
-
-#if 0
-        case OMX_EventBufferFlag:
-        {
-            CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
-
-            if (data1 == kPortIndexOutput) {
-                mNoMoreOutputData = true;
-            }
-            break;
-        }
-#endif
-
-        default:
-        {
-            CODEC_LOGV("EVENT(%d, %u, %u)", event, data1, data2);
-            break;
-        }
-    }
-}
-
-void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
-    switch (cmd) {
-        case OMX_CommandStateSet:
-        {
-            onStateChange((OMX_STATETYPE)data);
-            break;
-        }
-
-        case OMX_CommandPortDisable:
-        {
-            OMX_U32 portIndex = data;
-            CODEC_LOGV("PORT_DISABLED(%u)", portIndex);
-
-            CHECK(mState == EXECUTING || mState == RECONFIGURING);
-            CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING);
-            CHECK_EQ(mPortBuffers[portIndex].size(), 0u);
-
-            mPortStatus[portIndex] = DISABLED;
-
-            if (mState == RECONFIGURING) {
-                CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
-
-                sp<MetaData> oldOutputFormat = mOutputFormat;
-                initOutputFormat(mSource->getFormat());
-
-                // Don't notify clients if the output port settings change
-                // wasn't of importance to them, i.e. it may be that just the
-                // number of buffers has changed and nothing else.
-                bool formatChanged = formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
-                if (!mOutputPortSettingsHaveChanged) {
-                    mOutputPortSettingsHaveChanged = formatChanged;
-                }
-
-                status_t err = enablePortAsync(portIndex);
-                if (err != OK) {
-                    CODEC_LOGE("enablePortAsync(%u) failed (err = %d)", portIndex, err);
-                    setState(ERROR);
-                } else {
-                    err = allocateBuffersOnPort(portIndex);
-                    if (err != OK) {
-                        CODEC_LOGE("allocateBuffersOnPort (%s) failed "
-                                   "(err = %d)",
-                                   portIndex == kPortIndexInput
-                                        ? "input" : "output",
-                                   err);
-
-                        setState(ERROR);
-                    }
-                }
-            }
-            break;
-        }
-
-        case OMX_CommandPortEnable:
-        {
-            OMX_U32 portIndex = data;
-            CODEC_LOGV("PORT_ENABLED(%u)", portIndex);
-
-            CHECK(mState == EXECUTING || mState == RECONFIGURING);
-            CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING);
-
-            mPortStatus[portIndex] = ENABLED;
-
-            if (mState == RECONFIGURING) {
-                CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
-
-                setState(EXECUTING);
-
-                fillOutputBuffers();
-            }
-            break;
-        }
-
-        case OMX_CommandFlush:
-        {
-            OMX_U32 portIndex = data;
-
-            CODEC_LOGV("FLUSH_DONE(%u)", portIndex);
-
-            CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN);
-            mPortStatus[portIndex] = ENABLED;
-
-            CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]),
-                     mPortBuffers[portIndex].size());
-
-            if (mSkipCutBuffer != NULL && mPortStatus[kPortIndexOutput] == ENABLED) {
-                mSkipCutBuffer->clear();
-            }
-
-            if (mState == RECONFIGURING) {
-                CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
-
-                disablePortAsync(portIndex);
-            } else if (mState == EXECUTING_TO_IDLE) {
-                if (mPortStatus[kPortIndexInput] == ENABLED
-                    && mPortStatus[kPortIndexOutput] == ENABLED) {
-                    CODEC_LOGV("Finished flushing both ports, now completing "
-                         "transition from EXECUTING to IDLE.");
-
-                    mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
-                    mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
-
-                    status_t err =
-                        mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
-                    CHECK_EQ(err, (status_t)OK);
-                }
-            } else {
-                // We're flushing both ports in preparation for seeking.
-
-                if (mPortStatus[kPortIndexInput] == ENABLED
-                    && mPortStatus[kPortIndexOutput] == ENABLED) {
-                    CODEC_LOGV("Finished flushing both ports, now continuing from"
-                         " seek-time.");
-
-                    // We implicitly resume pulling on our upstream source.
-                    mPaused = false;
-
-                    drainInputBuffers();
-                    fillOutputBuffers();
-                }
-
-                if (mOutputPortSettingsChangedPending) {
-                    CODEC_LOGV(
-                            "Honoring deferred output port settings change.");
-
-                    mOutputPortSettingsChangedPending = false;
-                    onPortSettingsChanged(kPortIndexOutput);
-                }
-            }
-
-            break;
-        }
-
-        default:
-        {
-            CODEC_LOGV("CMD_COMPLETE(%d, %u)", cmd, data);
-            break;
-        }
-    }
-}
-
-void OMXCodec::onStateChange(OMX_STATETYPE newState) {
-    CODEC_LOGV("onStateChange %d", newState);
-
-    switch (newState) {
-        case OMX_StateIdle:
-        {
-            CODEC_LOGV("Now Idle.");
-            if (mState == LOADED_TO_IDLE) {
-                status_t err = mOMX->sendCommand(
-                        mNode, OMX_CommandStateSet, OMX_StateExecuting);
-
-                CHECK_EQ(err, (status_t)OK);
-
-                setState(IDLE_TO_EXECUTING);
-            } else {
-                CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE);
-
-                if (countBuffersWeOwn(mPortBuffers[kPortIndexInput]) !=
-                    mPortBuffers[kPortIndexInput].size()) {
-                    ALOGE("Codec did not return all input buffers "
-                          "(received %zu / %zu)",
-                            countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
-                            mPortBuffers[kPortIndexInput].size());
-                    TRESPASS();
-                }
-
-                if (countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) !=
-                    mPortBuffers[kPortIndexOutput].size()) {
-                    ALOGE("Codec did not return all output buffers "
-                          "(received %zu / %zu)",
-                            countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
-                            mPortBuffers[kPortIndexOutput].size());
-                    TRESPASS();
-                }
-
-                status_t err = mOMX->sendCommand(
-                        mNode, OMX_CommandStateSet, OMX_StateLoaded);
-
-                CHECK_EQ(err, (status_t)OK);
-
-                err = freeBuffersOnPort(kPortIndexInput);
-                CHECK_EQ(err, (status_t)OK);
-
-                err = freeBuffersOnPort(kPortIndexOutput);
-                CHECK_EQ(err, (status_t)OK);
-
-                mPortStatus[kPortIndexInput] = ENABLED;
-                mPortStatus[kPortIndexOutput] = ENABLED;
-
-                if ((mFlags & kEnableGrallocUsageProtected) &&
-                        mNativeWindow != NULL) {
-                    // We push enough 1x1 blank buffers to ensure that one of
-                    // them has made it to the display.  This allows the OMX
-                    // component teardown to zero out any protected buffers
-                    // without the risk of scanning out one of those buffers.
-                    pushBlankBuffersToNativeWindow(mNativeWindow.get());
-                }
-
-                setState(IDLE_TO_LOADED);
-            }
-            break;
-        }
-
-        case OMX_StateExecuting:
-        {
-            CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING);
-
-            CODEC_LOGV("Now Executing.");
-
-            mOutputPortSettingsChangedPending = false;
-
-            setState(EXECUTING);
-
-            // Buffers will be submitted to the component in the first
-            // call to OMXCodec::read as mInitialBufferSubmit is true at
-            // this point. This ensures that this on_message call returns,
-            // releases the lock and ::init can notice the state change and
-            // itself return.
-            break;
-        }
-
-        case OMX_StateLoaded:
-        {
-            CHECK_EQ((int)mState, (int)IDLE_TO_LOADED);
-
-            CODEC_LOGV("Now Loaded.");
-
-            setState(LOADED);
-            break;
-        }
-
-        case OMX_StateInvalid:
-        {
-            setState(ERROR);
-            break;
-        }
-
-        default:
-        {
-            CHECK(!"should not be here.");
-            break;
-        }
-    }
-}
-
-// static
-size_t OMXCodec::countBuffersWeOwn(const Vector<BufferInfo> &buffers) {
-    size_t n = 0;
-    for (size_t i = 0; i < buffers.size(); ++i) {
-        if (buffers[i].mStatus != OWNED_BY_COMPONENT) {
-            ++n;
-        }
-    }
-
-    return n;
-}
-
-status_t OMXCodec::freeBuffersOnPort(
-        OMX_U32 portIndex, bool onlyThoseWeOwn) {
-    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
-
-    status_t stickyErr = OK;
-
-    for (size_t i = buffers->size(); i > 0;) {
-        i--;
-        BufferInfo *info = &buffers->editItemAt(i);
-
-        if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) {
-            continue;
-        }
-
-        CHECK(info->mStatus == OWNED_BY_US
-                || info->mStatus == OWNED_BY_NATIVE_WINDOW);
-
-        CODEC_LOGV("freeing buffer %u on port %u", info->mBuffer, portIndex);
-
-        status_t err = freeBuffer(portIndex, i);
-
-        if (err != OK) {
-            stickyErr = err;
-        }
-
-    }
-
-    CHECK(onlyThoseWeOwn || buffers->isEmpty());
-
-    return stickyErr;
-}
-
-status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) {
-    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
-
-    BufferInfo *info = &buffers->editItemAt(bufIndex);
-
-    status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
-
-    if (err == OK && info->mMediaBuffer != NULL) {
-        CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
-        info->mMediaBuffer->setObserver(NULL);
-
-        // Make sure nobody but us owns this buffer at this point.
-        CHECK_EQ(info->mMediaBuffer->refcount(), 0);
-
-        // Cancel the buffer if it belongs to an ANativeWindow.
-        sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
-        if (info->mStatus == OWNED_BY_US && graphicBuffer != 0) {
-            err = cancelBufferToNativeWindow(info);
-        }
-
-        info->mMediaBuffer->release();
-        info->mMediaBuffer = NULL;
-    }
-
-    if (err == OK) {
-        buffers->removeAt(bufIndex);
-    }
-
-    return err;
-}
-
-void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
-    CODEC_LOGV("PORT_SETTINGS_CHANGED(%u)", portIndex);
-
-    CHECK(mState == EXECUTING || mState == EXECUTING_TO_IDLE);
-    CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
-    CHECK(!mOutputPortSettingsChangedPending);
-
-    if (mPortStatus[kPortIndexOutput] != ENABLED) {
-        CODEC_LOGV("Deferring output port settings change.");
-        mOutputPortSettingsChangedPending = true;
-        return;
-    }
-
-    setState(RECONFIGURING);
-
-    if (mQuirks & kNeedsFlushBeforeDisable) {
-        if (!flushPortAsync(portIndex)) {
-            onCmdComplete(OMX_CommandFlush, portIndex);
-        }
-    } else {
-        disablePortAsync(portIndex);
-    }
-}
-
-bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
-    CHECK(mState == EXECUTING || mState == RECONFIGURING
-            || mState == EXECUTING_TO_IDLE);
-
-    CODEC_LOGV("flushPortAsync(%u): we own %zu out of %zu buffers already.",
-         portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
-         mPortBuffers[portIndex].size());
-
-    CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
-    mPortStatus[portIndex] = SHUTTING_DOWN;
-
-    if ((mQuirks & kRequiresFlushCompleteEmulation)
-        && countBuffersWeOwn(mPortBuffers[portIndex])
-                == mPortBuffers[portIndex].size()) {
-        // No flush is necessary and this component fails to send a
-        // flush-complete event in this case.
-
-        return false;
-    }
-
-    status_t err =
-        mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex);
-    CHECK_EQ(err, (status_t)OK);
-
-    return true;
-}
-
-void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
-    CHECK(mState == EXECUTING || mState == RECONFIGURING);
-
-    CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
-    mPortStatus[portIndex] = DISABLING;
-
-    CODEC_LOGV("sending OMX_CommandPortDisable(%u)", portIndex);
-    status_t err =
-        mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
-    CHECK_EQ(err, (status_t)OK);
-
-    freeBuffersOnPort(portIndex, true);
-}
-
-status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) {
-    CHECK(mState == EXECUTING || mState == RECONFIGURING);
-
-    CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED);
-    mPortStatus[portIndex] = ENABLING;
-
-    CODEC_LOGV("sending OMX_CommandPortEnable(%u)", portIndex);
-    return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
-}
-
-void OMXCodec::fillOutputBuffers() {
-    CHECK_EQ((int)mState, (int)EXECUTING);
-
-    // This is a workaround for some decoders not properly reporting
-    // end-of-output-stream. If we own all input buffers and also own
-    // all output buffers and we already signalled end-of-input-stream,
-    // the end-of-output-stream is implied.
-    if (mSignalledEOS
-            && countBuffersWeOwn(mPortBuffers[kPortIndexInput])
-                == mPortBuffers[kPortIndexInput].size()
-            && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
-                == mPortBuffers[kPortIndexOutput].size()) {
-        mNoMoreOutputData = true;
-        mBufferFilled.signal();
-
-        return;
-    }
-
-    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
-    for (size_t i = 0; i < buffers->size(); ++i) {
-        BufferInfo *info = &buffers->editItemAt(i);
-        if (info->mStatus == OWNED_BY_US) {
-            fillOutputBuffer(&buffers->editItemAt(i));
-        }
-    }
-}
-
-void OMXCodec::drainInputBuffers() {
-    CHECK(mState == EXECUTING || mState == RECONFIGURING);
-
-    if (mFlags & kUseSecureInputBuffers) {
-        Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
-        for (size_t i = 0; i < buffers->size(); ++i) {
-            if (!drainAnyInputBuffer()
-                    || (mFlags & kOnlySubmitOneInputBufferAtOneTime)) {
-                break;
-            }
-        }
-    } else {
-        Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
-        for (size_t i = 0; i < buffers->size(); ++i) {
-            BufferInfo *info = &buffers->editItemAt(i);
-
-            if (info->mStatus != OWNED_BY_US) {
-                continue;
-            }
-
-            if (!drainInputBuffer(info)) {
-                break;
-            }
-
-            if (mFlags & kOnlySubmitOneInputBufferAtOneTime) {
-                break;
-            }
-        }
-    }
-}
-
-bool OMXCodec::drainAnyInputBuffer() {
-    return drainInputBuffer((BufferInfo *)NULL);
-}
-
-OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) {
-    Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
-    for (size_t i = 0; i < infos->size(); ++i) {
-        BufferInfo *info = &infos->editItemAt(i);
-
-        if (info->mData == ptr) {
-            CODEC_LOGV(
-                    "input buffer data ptr = %p, buffer_id = %u",
-                    ptr,
-                    info->mBuffer);
-
-            return info;
-        }
-    }
-
-    TRESPASS();
-}
-
-OMXCodec::BufferInfo *OMXCodec::findEmptyInputBuffer() {
-    Vector<BufferInfo> *infos = &mPortBuffers[kPortIndexInput];
-    for (size_t i = 0; i < infos->size(); ++i) {
-        BufferInfo *info = &infos->editItemAt(i);
-
-        if (info->mStatus == OWNED_BY_US) {
-            return info;
-        }
-    }
-
-    TRESPASS();
-}
-
-bool OMXCodec::drainInputBuffer(BufferInfo *info) {
-    if (info != NULL) {
-        CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
-    }
-
-    if (mSignalledEOS) {
-        return false;
-    }
-
-    if (mCodecSpecificDataIndex < mCodecSpecificData.size()) {
-        CHECK(!(mFlags & kUseSecureInputBuffers));
-
-        const CodecSpecificData *specific =
-            mCodecSpecificData[mCodecSpecificDataIndex];
-
-        size_t size = specific->mSize;
-
-        if ((!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) ||
-             !strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mMIME))
-                && !(mQuirks & kWantsNALFragments)) {
-            static const uint8_t kNALStartCode[4] =
-                    { 0x00, 0x00, 0x00, 0x01 };
-
-            CHECK(info->mSize >= specific->mSize + 4);
-
-            size += 4;
-
-            memcpy(info->mData, kNALStartCode, 4);
-            memcpy((uint8_t *)info->mData + 4,
-                   specific->mData, specific->mSize);
-        } else {
-            CHECK(info->mSize >= specific->mSize);
-            memcpy(info->mData, specific->mData, specific->mSize);
-        }
-
-        mNoMoreOutputData = false;
-
-        CODEC_LOGV("calling emptyBuffer with codec specific data");
-
-        status_t err = mOMX->emptyBuffer(
-                mNode, info->mBuffer, 0, size,
-                OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
-                0);
-        CHECK_EQ(err, (status_t)OK);
-
-        info->mStatus = OWNED_BY_COMPONENT;
-
-        ++mCodecSpecificDataIndex;
-        return true;
-    }
-
-    if (mPaused) {
-        return false;
-    }
-
-    status_t err;
-
-    bool signalEOS = false;
-    int64_t timestampUs = 0;
-
-    size_t offset = 0;
-    int32_t n = 0;
-
-
-    for (;;) {
-        MediaBuffer *srcBuffer;
-        if (mSeekTimeUs >= 0) {
-            if (mLeftOverBuffer) {
-                mLeftOverBuffer->release();
-                mLeftOverBuffer = NULL;
-            }
-
-            MediaSource::ReadOptions options;
-            options.setSeekTo(mSeekTimeUs, mSeekMode);
-
-            mSeekTimeUs = -1;
-            mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
-            mBufferFilled.signal();
-
-            err = mSource->read(&srcBuffer, &options);
-
-            if (err == OK) {
-                int64_t targetTimeUs;
-                if (srcBuffer->meta_data()->findInt64(
-                            kKeyTargetTime, &targetTimeUs)
-                        && targetTimeUs >= 0) {
-                    CODEC_LOGV("targetTimeUs = %lld us", (long long)targetTimeUs);
-                    mTargetTimeUs = targetTimeUs;
-                } else {
-                    mTargetTimeUs = -1;
-                }
-            }
-        } else if (mLeftOverBuffer) {
-            srcBuffer = mLeftOverBuffer;
-            mLeftOverBuffer = NULL;
-
-            err = OK;
-        } else {
-            err = mSource->read(&srcBuffer);
-        }
-
-        if (err != OK) {
-            signalEOS = true;
-            mFinalStatus = err;
-            mSignalledEOS = true;
-            mBufferFilled.signal();
-            break;
-        }
-
-        if (mFlags & kUseSecureInputBuffers) {
-            info = findInputBufferByDataPointer(srcBuffer->data());
-            CHECK(info != NULL);
-        }
-
-        size_t remainingBytes = info->mSize - offset;
-
-        if (srcBuffer->range_length() > remainingBytes) {
-            if (offset == 0) {
-                CODEC_LOGE(
-                     "Codec's input buffers are too small to accomodate "
-                     "buffer read from source (info->mSize = %zu, srcLength = %zu)",
-                     info->mSize, srcBuffer->range_length());
-
-                srcBuffer->release();
-                srcBuffer = NULL;
-
-                setState(ERROR);
-                return false;
-            }
-
-            mLeftOverBuffer = srcBuffer;
-            break;
-        }
-
-        bool releaseBuffer = true;
-        if (mFlags & kStoreMetaDataInVideoBuffers) {
-                releaseBuffer = false;
-                info->mMediaBuffer = srcBuffer;
-        }
-
-        if (mFlags & kUseSecureInputBuffers) {
-                // Data in "info" is already provided at this time.
-
-                releaseBuffer = false;
-
-                CHECK(info->mMediaBuffer == NULL);
-                info->mMediaBuffer = srcBuffer;
-        } else {
-            CHECK(srcBuffer->data() != NULL) ;
-            memcpy((uint8_t *)info->mData + offset,
-                    (const uint8_t *)srcBuffer->data()
-                        + srcBuffer->range_offset(),
-                    srcBuffer->range_length());
-        }
-
-        int64_t lastBufferTimeUs;
-        CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
-        CHECK(lastBufferTimeUs >= 0);
-        if (mIsEncoder && mIsVideo) {
-            mDecodingTimeList.push_back(lastBufferTimeUs);
-        }
-
-        if (offset == 0) {
-            timestampUs = lastBufferTimeUs;
-        }
-
-        offset += srcBuffer->range_length();
-
-        if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_VORBIS, mMIME)) {
-            CHECK(!(mQuirks & kSupportsMultipleFramesPerInputBuffer));
-            CHECK_GE(info->mSize, offset + sizeof(int32_t));
-
-            int32_t numPageSamples;
-            if (!srcBuffer->meta_data()->findInt32(
-                        kKeyValidSamples, &numPageSamples)) {
-                numPageSamples = -1;
-            }
-
-            memcpy((uint8_t *)info->mData + offset,
-                   &numPageSamples,
-                   sizeof(numPageSamples));
-
-            offset += sizeof(numPageSamples);
-        }
-
-        if (releaseBuffer) {
-            srcBuffer->release();
-            srcBuffer = NULL;
-        }
-
-        ++n;
-
-        if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
-            break;
-        }
-
-        int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs;
-
-        if (coalescedDurationUs > 250000ll) {
-            // Don't coalesce more than 250ms worth of encoded data at once.
-            break;
-        }
-    }
-
-    if (n > 1) {
-        ALOGV("coalesced %d frames into one input buffer", n);
-    }
-
-    OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
-
-    if (signalEOS) {
-        flags |= OMX_BUFFERFLAG_EOS;
-    } else {
-        mNoMoreOutputData = false;
-    }
-
-    if (info == NULL) {
-        CHECK(mFlags & kUseSecureInputBuffers);
-        CHECK(signalEOS);
-
-        // This is fishy, there's still a MediaBuffer corresponding to this
-        // info available to the source at this point even though we're going
-        // to use it to signal EOS to the codec.
-        info = findEmptyInputBuffer();
-    }
-
-    CODEC_LOGV("Calling emptyBuffer on buffer %u (length %zu), "
-               "timestamp %lld us (%.2f secs)",
-               info->mBuffer, offset,
-               (long long)timestampUs, timestampUs / 1E6);
-
-    err = mOMX->emptyBuffer(
-            mNode, info->mBuffer, 0, offset,
-            flags, timestampUs);
-
-    if (err != OK) {
-        setState(ERROR);
-        return false;
-    }
-
-    info->mStatus = OWNED_BY_COMPONENT;
-
-    return true;
-}
-
-void OMXCodec::fillOutputBuffer(BufferInfo *info) {
-    CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
-
-    if (mNoMoreOutputData) {
-        CODEC_LOGV("There is no more output data available, not "
-             "calling fillOutputBuffer");
-        return;
-    }
-
-    CODEC_LOGV("Calling fillBuffer on buffer %u", info->mBuffer);
-    status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
-
-    if (err != OK) {
-        CODEC_LOGE("fillBuffer failed w/ error 0x%08x", err);
-
-        setState(ERROR);
-        return;
-    }
-
-    info->mStatus = OWNED_BY_COMPONENT;
-}
-
-bool OMXCodec::drainInputBuffer(IOMX::buffer_id buffer) {
-    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
-    for (size_t i = 0; i < buffers->size(); ++i) {
-        if ((*buffers)[i].mBuffer == buffer) {
-            return drainInputBuffer(&buffers->editItemAt(i));
-        }
-    }
-
-    CHECK(!"should not be here.");
-
-    return false;
-}
-
-void OMXCodec::fillOutputBuffer(IOMX::buffer_id buffer) {
-    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
-    for (size_t i = 0; i < buffers->size(); ++i) {
-        if ((*buffers)[i].mBuffer == buffer) {
-            fillOutputBuffer(&buffers->editItemAt(i));
-            return;
-        }
-    }
-
-    CHECK(!"should not be here.");
-}
-
-void OMXCodec::setState(State newState) {
-    mState = newState;
-    mAsyncCompletion.signal();
-
-    // This may cause some spurious wakeups but is necessary to
-    // unblock the reader if we enter ERROR state.
-    mBufferFilled.signal();
-}
-
-status_t OMXCodec::waitForBufferFilled_l() {
-
-    if (mIsEncoder) {
-        // For timelapse video recording, the timelapse video recording may
-        // not send an input frame for a _long_ time. Do not use timeout
-        // for video encoding.
-        return mBufferFilled.wait(mLock);
-    }
-    status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs);
-    if (err != OK) {
-        CODEC_LOGE("Timed out waiting for output buffers: %zu/%zu",
-            countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
-            countBuffersWeOwn(mPortBuffers[kPortIndexOutput]));
-    }
-    return err;
-}
-
-void OMXCodec::setRawAudioFormat(
-        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
-
-    // port definition
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = portIndex;
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
-    CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
-            &def, sizeof(def)), (status_t)OK);
-
-    // pcm param
-    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
-    InitOMXParams(&pcmParams);
-    pcmParams.nPortIndex = portIndex;
-
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
-
-    CHECK_EQ(err, (status_t)OK);
-
-    pcmParams.nChannels = numChannels;
-    pcmParams.eNumData = OMX_NumericalDataSigned;
-    pcmParams.bInterleaved = OMX_TRUE;
-    pcmParams.nBitPerSample = 16;
-    pcmParams.nSamplingRate = sampleRate;
-    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
-
-    CHECK_EQ(ACodec::getOMXChannelMapping(
-                numChannels, pcmParams.eChannelMapping), (status_t)OK);
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
-
-    CHECK_EQ(err, (status_t)OK);
-}
-
-static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) {
-    if (isAMRWB) {
-        if (bps <= 6600) {
-            return OMX_AUDIO_AMRBandModeWB0;
-        } else if (bps <= 8850) {
-            return OMX_AUDIO_AMRBandModeWB1;
-        } else if (bps <= 12650) {
-            return OMX_AUDIO_AMRBandModeWB2;
-        } else if (bps <= 14250) {
-            return OMX_AUDIO_AMRBandModeWB3;
-        } else if (bps <= 15850) {
-            return OMX_AUDIO_AMRBandModeWB4;
-        } else if (bps <= 18250) {
-            return OMX_AUDIO_AMRBandModeWB5;
-        } else if (bps <= 19850) {
-            return OMX_AUDIO_AMRBandModeWB6;
-        } else if (bps <= 23050) {
-            return OMX_AUDIO_AMRBandModeWB7;
-        }
-
-        // 23850 bps
-        return OMX_AUDIO_AMRBandModeWB8;
-    } else {  // AMRNB
-        if (bps <= 4750) {
-            return OMX_AUDIO_AMRBandModeNB0;
-        } else if (bps <= 5150) {
-            return OMX_AUDIO_AMRBandModeNB1;
-        } else if (bps <= 5900) {
-            return OMX_AUDIO_AMRBandModeNB2;
-        } else if (bps <= 6700) {
-            return OMX_AUDIO_AMRBandModeNB3;
-        } else if (bps <= 7400) {
-            return OMX_AUDIO_AMRBandModeNB4;
-        } else if (bps <= 7950) {
-            return OMX_AUDIO_AMRBandModeNB5;
-        } else if (bps <= 10200) {
-            return OMX_AUDIO_AMRBandModeNB6;
-        }
-
-        // 12200 bps
-        return OMX_AUDIO_AMRBandModeNB7;
-    }
-}
-
-void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) {
-    OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
-
-    OMX_AUDIO_PARAM_AMRTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = portIndex;
-
-    status_t err =
-        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
-
-    CHECK_EQ(err, (status_t)OK);
-
-    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
-
-    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate);
-    err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    ////////////////////////
-
-    if (mIsEncoder) {
-        sp<MetaData> format = mSource->getFormat();
-        int32_t sampleRate;
-        int32_t numChannels;
-        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
-        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
-
-        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
-    }
-}
-
-status_t OMXCodec::setAACFormat(
-        int32_t numChannels, int32_t sampleRate, int32_t bitRate, int32_t aacProfile, bool isADTS) {
-    if (numChannels > 2) {
-        ALOGW("Number of channels: (%d) \n", numChannels);
-    }
-
-    if (mIsEncoder) {
-        if (isADTS) {
-            return -EINVAL;
-        }
-
-        //////////////// input port ////////////////////
-        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
-
-        //////////////// output port ////////////////////
-        // format
-        OMX_AUDIO_PARAM_PORTFORMATTYPE format;
-        InitOMXParams(&format);
-        format.nPortIndex = kPortIndexOutput;
-        format.nIndex = 0;
-        status_t err = OMX_ErrorNone;
-        while (OMX_ErrorNone == err) {
-            CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat,
-                    &format, sizeof(format)), (status_t)OK);
-            if (format.eEncoding == OMX_AUDIO_CodingAAC) {
-                break;
-            }
-            format.nIndex++;
-        }
-        CHECK_EQ((status_t)OK, err);
-        CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat,
-                &format, sizeof(format)), (status_t)OK);
-
-        // port definition
-        OMX_PARAM_PORTDEFINITIONTYPE def;
-        InitOMXParams(&def);
-        def.nPortIndex = kPortIndexOutput;
-        CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition,
-                &def, sizeof(def)), (status_t)OK);
-        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
-        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
-        CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition,
-                &def, sizeof(def)), (status_t)OK);
-
-        // profile
-        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
-        InitOMXParams(&profile);
-        profile.nPortIndex = kPortIndexOutput;
-        CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac,
-                &profile, sizeof(profile)), (status_t)OK);
-        profile.nChannels = numChannels;
-        profile.eChannelMode = (numChannels == 1?
-                OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo);
-        profile.nSampleRate = sampleRate;
-        profile.nBitRate = bitRate;
-        profile.nAudioBandWidth = 0;
-        profile.nFrameLength = 0;
-        profile.nAACtools = OMX_AUDIO_AACToolAll;
-        profile.nAACERtools = OMX_AUDIO_AACERNone;
-        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
-        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
-        err = mOMX->setParameter(mNode, OMX_IndexParamAudioAac,
-                &profile, sizeof(profile));
-
-        if (err != OK) {
-            CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
-                       "(err = %d)",
-                       err);
-            return err;
-        }
-    } else {
-        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
-        InitOMXParams(&profile);
-        profile.nPortIndex = kPortIndexInput;
-
-        status_t err = mOMX->getParameter(
-                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
-        CHECK_EQ(err, (status_t)OK);
-
-        profile.nChannels = numChannels;
-        profile.nSampleRate = sampleRate;
-
-        profile.eAACStreamFormat =
-            isADTS
-                ? OMX_AUDIO_AACStreamFormatMP4ADTS
-                : OMX_AUDIO_AACStreamFormatMP4FF;
-
-        err = mOMX->setParameter(
-                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
-
-        if (err != OK) {
-            CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
-                       "(err = %d)",
-                       err);
-            return err;
-        }
-    }
-
-    return OK;
-}
-
-status_t OMXCodec::setAC3Format(int32_t numChannels, int32_t sampleRate) {
-    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexInput;
-
-    status_t err = mOMX->getParameter(
-            mNode,
-            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
-            &def,
-            sizeof(def));
-
-    if (err != OK) {
-        return err;
-    }
-
-    def.nChannels = numChannels;
-    def.nSampleRate = sampleRate;
-
-    return mOMX->setParameter(
-            mNode,
-            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
-            &def,
-            sizeof(def));
-}
-
-void OMXCodec::setG711Format(int32_t sampleRate, int32_t numChannels) {
-    CHECK(!mIsEncoder);
-    setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
-}
-
-void OMXCodec::setImageOutputFormat(
-        OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
-    CODEC_LOGV("setImageOutputFormat(%u, %u)", width, height);
-
-#if 0
-    OMX_INDEXTYPE index;
-    status_t err = mOMX->get_extension_index(
-            mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index);
-    CHECK_EQ(err, (status_t)OK);
-
-    err = mOMX->set_config(mNode, index, &format, sizeof(format));
-    CHECK_EQ(err, (status_t)OK);
-#endif
-
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexOutput;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
-
-    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
-
-    CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused);
-    imageDef->eColorFormat = format;
-    imageDef->nFrameWidth = width;
-    imageDef->nFrameHeight = height;
-
-    switch (format) {
-        case OMX_COLOR_FormatYUV420PackedPlanar:
-        case OMX_COLOR_FormatYUV411Planar:
-        {
-            def.nBufferSize = (width * height * 3) / 2;
-            break;
-        }
-
-        case OMX_COLOR_FormatCbYCrY:
-        {
-            def.nBufferSize = width * height * 2;
-            break;
-        }
-
-        case OMX_COLOR_Format32bitARGB8888:
-        {
-            def.nBufferSize = width * height * 4;
-            break;
-        }
-
-        case OMX_COLOR_Format16bitARGB4444:
-        case OMX_COLOR_Format16bitARGB1555:
-        case OMX_COLOR_Format16bitRGB565:
-        case OMX_COLOR_Format16bitBGR565:
-        {
-            def.nBufferSize = width * height * 2;
-            break;
-        }
-
-        default:
-            CHECK(!"Should not be here. Unknown color format.");
-            break;
-    }
-
-    def.nBufferCountActual = def.nBufferCountMin;
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-}
-
-void OMXCodec::setJPEGInputFormat(
-        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexInput;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage);
-    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
-
-    CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG);
-    imageDef->nFrameWidth = width;
-    imageDef->nFrameHeight = height;
-
-    def.nBufferSize = compressedSize;
-    def.nBufferCountActual = def.nBufferCountMin;
-
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-}
-
-void OMXCodec::addCodecSpecificData(const void *data, size_t size) {
-
-    if (size > SIZE_MAX - (sizeof(CodecSpecificData) - 1)) {
-        // this would require the size to be ~4GB, which should be near impossible
-        // given that it is the size of an in-memory chunk of data
-        ALOGE("b/23540411");
-        return;
-    }
-
-    CodecSpecificData *specific =
-        (CodecSpecificData *)malloc(sizeof(CodecSpecificData) - 1 + size);
-
-    if (specific == NULL) {
-        ALOGE("b/23540411");
-        return;
-    }
-
-    specific->mSize = size;
-    memcpy(specific->mData, data, size);
-
-    mCodecSpecificData.push(specific);
-}
-
-void OMXCodec::clearCodecSpecificData() {
-    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
-        free(mCodecSpecificData.editItemAt(i));
-    }
-    mCodecSpecificData.clear();
-    mCodecSpecificDataIndex = 0;
-}
-
-status_t OMXCodec::start(MetaData *meta) {
-    Mutex::Autolock autoLock(mLock);
-
-    if (mState != LOADED) {
-        CODEC_LOGE("called start in the unexpected state: %d", mState);
-        return UNKNOWN_ERROR;
-    }
-
-    sp<MetaData> params = new MetaData;
-    if (mQuirks & kWantsNALFragments) {
-        params->setInt32(kKeyWantsNALFragments, true);
-    }
-    if (meta) {
-        int64_t startTimeUs = 0;
-        int64_t timeUs;
-        if (meta->findInt64(kKeyTime, &timeUs)) {
-            startTimeUs = timeUs;
-        }
-        params->setInt64(kKeyTime, startTimeUs);
-    }
-
-    mCodecSpecificDataIndex = 0;
-    mInitialBufferSubmit = true;
-    mSignalledEOS = false;
-    mNoMoreOutputData = false;
-    mOutputPortSettingsHaveChanged = false;
-    mSeekTimeUs = -1;
-    mSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
-    mTargetTimeUs = -1;
-    mFilledBuffers.clear();
-    mPaused = false;
-
-    status_t err;
-    if (mIsEncoder) {
-        // Calling init() before starting its source so that we can configure,
-        // if supported, the source to use exactly the same number of input
-        // buffers as requested by the encoder.
-        if ((err = init()) != OK) {
-            CODEC_LOGE("init failed: %d", err);
-            return err;
-        }
-
-        params->setInt32(kKeyNumBuffers, mPortBuffers[kPortIndexInput].size());
-        err = mSource->start(params.get());
-        if (err != OK) {
-            CODEC_LOGE("source failed to start: %d", err);
-            stopOmxComponent_l();
-        }
-        return err;
-    }
-
-    // Decoder case
-    if ((err = mSource->start(params.get())) != OK) {
-        CODEC_LOGE("source failed to start: %d", err);
-        return err;
-    }
-    return init();
-}
-
-status_t OMXCodec::stop() {
-    CODEC_LOGV("stop mState=%d", mState);
-    Mutex::Autolock autoLock(mLock);
-    status_t err = stopOmxComponent_l();
-    mSource->stop();
-
-    CODEC_LOGV("stopped in state %d", mState);
-    return err;
-}
-
-status_t OMXCodec::stopOmxComponent_l() {
-    CODEC_LOGV("stopOmxComponent_l mState=%d", mState);
-
-    while (isIntermediateState(mState)) {
-        mAsyncCompletion.wait(mLock);
-    }
-
-    bool isError = false;
-    switch (mState) {
-        case LOADED:
-            break;
-
-        case ERROR:
-        {
-            if (mPortStatus[kPortIndexOutput] == ENABLING) {
-                // Codec is in a wedged state (technical term)
-                // We've seen an output port settings change from the codec,
-                // We've disabled the output port, then freed the output
-                // buffers, initiated re-enabling the output port but
-                // failed to reallocate the output buffers.
-                // There doesn't seem to be a way to orderly transition
-                // from executing->idle and idle->loaded now that the
-                // output port hasn't been reenabled yet...
-                // Simply free as many resources as we can and pretend
-                // that we're in LOADED state so that the destructor
-                // will free the component instance without asserting.
-                freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */);
-                freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */);
-                setState(LOADED);
-                break;
-            } else {
-                OMX_STATETYPE state = OMX_StateInvalid;
-                status_t err = mOMX->getState(mNode, &state);
-                CHECK_EQ(err, (status_t)OK);
-
-                if (state != OMX_StateExecuting) {
-                    break;
-                }
-                // else fall through to the idling code
-            }
-
-            isError = true;
-        }
-
-        case EXECUTING:
-        {
-            setState(EXECUTING_TO_IDLE);
-
-            if (mQuirks & kRequiresFlushBeforeShutdown) {
-                CODEC_LOGV("This component requires a flush before transitioning "
-                     "from EXECUTING to IDLE...");
-
-                bool emulateInputFlushCompletion =
-                    !flushPortAsync(kPortIndexInput);
-
-                bool emulateOutputFlushCompletion =
-                    !flushPortAsync(kPortIndexOutput);
-
-                if (emulateInputFlushCompletion) {
-                    onCmdComplete(OMX_CommandFlush, kPortIndexInput);
-                }
-
-                if (emulateOutputFlushCompletion) {
-                    onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
-                }
-            } else {
-                mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
-                mPortStatus[kPortIndexOutput] = SHUTTING_DOWN;
-
-                status_t err =
-                    mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
-                CHECK_EQ(err, (status_t)OK);
-            }
-
-            while (mState != LOADED && mState != ERROR) {
-                mAsyncCompletion.wait(mLock);
-            }
-
-            if (isError) {
-                // We were in the ERROR state coming in, so restore that now
-                // that we've idled the OMX component.
-                setState(ERROR);
-            }
-
-            break;
-        }
-
-        default:
-        {
-            CHECK(!"should not be here.");
-            break;
-        }
-    }
-
-    if (mLeftOverBuffer) {
-        mLeftOverBuffer->release();
-        mLeftOverBuffer = NULL;
-    }
-
-    return OK;
-}
-
-sp<MetaData> OMXCodec::getFormat() {
-    Mutex::Autolock autoLock(mLock);
-
-    return mOutputFormat;
-}
-
-status_t OMXCodec::read(
-        MediaBuffer **buffer, const ReadOptions *options) {
-    status_t err = OK;
-    *buffer = NULL;
-
-    Mutex::Autolock autoLock(mLock);
-
-    if (mState != EXECUTING && mState != RECONFIGURING) {
-        return UNKNOWN_ERROR;
-    }
-
-    bool seeking = false;
-    int64_t seekTimeUs;
-    ReadOptions::SeekMode seekMode;
-    if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
-        seeking = true;
-    }
-
-    if (mInitialBufferSubmit) {
-        mInitialBufferSubmit = false;
-
-        if (seeking) {
-            CHECK(seekTimeUs >= 0);
-            mSeekTimeUs = seekTimeUs;
-            mSeekMode = seekMode;
-
-            // There's no reason to trigger the code below, there's
-            // nothing to flush yet.
-            seeking = false;
-            mPaused = false;
-        }
-
-        drainInputBuffers();
-
-        if (mState == EXECUTING) {
-            // Otherwise mState == RECONFIGURING and this code will trigger
-            // after the output port is reenabled.
-            fillOutputBuffers();
-        }
-    }
-
-    if (seeking) {
-        while (mState == RECONFIGURING) {
-            if ((err = waitForBufferFilled_l()) != OK) {
-                return err;
-            }
-        }
-
-        if (mState != EXECUTING) {
-            return UNKNOWN_ERROR;
-        }
-
-        CODEC_LOGV("seeking to %" PRId64 " us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
-
-        mSignalledEOS = false;
-
-        CHECK(seekTimeUs >= 0);
-        mSeekTimeUs = seekTimeUs;
-        mSeekMode = seekMode;
-
-        mFilledBuffers.clear();
-
-        CHECK_EQ((int)mState, (int)EXECUTING);
-
-        bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput);
-        bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput);
-
-        if (emulateInputFlushCompletion) {
-            onCmdComplete(OMX_CommandFlush, kPortIndexInput);
-        }
-
-        if (emulateOutputFlushCompletion) {
-            onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
-        }
-
-        while (mSeekTimeUs >= 0) {
-            if ((err = waitForBufferFilled_l()) != OK) {
-                return err;
-            }
-        }
-    }
-
-    while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
-        if ((err = waitForBufferFilled_l()) != OK) {
-            return err;
-        }
-    }
-
-    if (mState == ERROR) {
-        return UNKNOWN_ERROR;
-    }
-
-    if (mFilledBuffers.empty()) {
-        return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
-    }
-
-    if (mOutputPortSettingsHaveChanged) {
-        mOutputPortSettingsHaveChanged = false;
-
-        return INFO_FORMAT_CHANGED;
-    }
-
-    size_t index = *mFilledBuffers.begin();
-    mFilledBuffers.erase(mFilledBuffers.begin());
-
-    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
-    CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
-    info->mStatus = OWNED_BY_CLIENT;
-
-    info->mMediaBuffer->add_ref();
-    if (mSkipCutBuffer != NULL) {
-        mSkipCutBuffer->submit(info->mMediaBuffer);
-    }
-    *buffer = info->mMediaBuffer;
-
-    return OK;
-}
-
-void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
-    Mutex::Autolock autoLock(mLock);
-
-    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
-    for (size_t i = 0; i < buffers->size(); ++i) {
-        BufferInfo *info = &buffers->editItemAt(i);
-
-        if (info->mMediaBuffer == buffer) {
-            CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED);
-            CHECK_EQ((int)info->mStatus, (int)OWNED_BY_CLIENT);
-
-            info->mStatus = OWNED_BY_US;
-
-            if (buffer->graphicBuffer() == 0) {
-                fillOutputBuffer(info);
-            } else {
-                sp<MetaData> metaData = info->mMediaBuffer->meta_data();
-                int32_t rendered = 0;
-                if (!metaData->findInt32(kKeyRendered, &rendered)) {
-                    rendered = 0;
-                }
-                if (!rendered) {
-                    status_t err = cancelBufferToNativeWindow(info);
-                    if (err < 0) {
-                        return;
-                    }
-                }
-
-                info->mStatus = OWNED_BY_NATIVE_WINDOW;
-
-                // Dequeue the next buffer from the native window.
-                BufferInfo *nextBufInfo = dequeueBufferFromNativeWindow();
-                if (nextBufInfo == 0) {
-                    return;
-                }
-
-                // Give the buffer to the OMX node to fill.
-                fillOutputBuffer(nextBufInfo);
-            }
-            return;
-        }
-    }
-
-    CHECK(!"should not be here.");
-}
-
-void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = portIndex;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output");
-
-    CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
-          || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
-
-    printf("  nBufferCountActual = %" PRIu32 "\n", def.nBufferCountActual);
-    printf("  nBufferCountMin = %" PRIu32 "\n", def.nBufferCountMin);
-    printf("  nBufferSize = %" PRIu32 "\n", def.nBufferSize);
-
-    switch (def.eDomain) {
-        case OMX_PortDomainImage:
-        {
-            const OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
-
-            printf("\n");
-            printf("  // Image\n");
-            printf("  nFrameWidth = %" PRIu32 "\n", imageDef->nFrameWidth);
-            printf("  nFrameHeight = %" PRIu32 "\n", imageDef->nFrameHeight);
-            printf("  nStride = %" PRIu32 "\n", imageDef->nStride);
-
-            printf("  eCompressionFormat = %s\n",
-                   asString(imageDef->eCompressionFormat));
-
-            printf("  eColorFormat = %s\n",
-                   asString(imageDef->eColorFormat));
-
-            break;
-        }
-
-        case OMX_PortDomainVideo:
-        {
-            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
-
-            printf("\n");
-            printf("  // Video\n");
-            printf("  nFrameWidth = %" PRIu32 "\n", videoDef->nFrameWidth);
-            printf("  nFrameHeight = %" PRIu32 "\n", videoDef->nFrameHeight);
-            printf("  nStride = %" PRIu32 "\n", videoDef->nStride);
-
-            printf("  eCompressionFormat = %s\n",
-                   asString(videoDef->eCompressionFormat));
-
-            printf("  eColorFormat = %s\n",
-                   asString(videoDef->eColorFormat));
-
-            break;
-        }
-
-        case OMX_PortDomainAudio:
-        {
-            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
-
-            printf("\n");
-            printf("  // Audio\n");
-            printf("  eEncoding = %s\n",
-                   asString(audioDef->eEncoding));
-
-            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
-                OMX_AUDIO_PARAM_PCMMODETYPE params;
-                InitOMXParams(&params);
-                params.nPortIndex = portIndex;
-
-                err = mOMX->getParameter(
-                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
-                CHECK_EQ(err, (status_t)OK);
-
-                printf("  nSamplingRate = %" PRIu32 "\n", params.nSamplingRate);
-                printf("  nChannels = %" PRIu32 "\n", params.nChannels);
-                printf("  bInterleaved = %d\n", params.bInterleaved);
-                printf("  nBitPerSample = %" PRIu32 "\n", params.nBitPerSample);
-
-                printf("  eNumData = %s\n",
-                       params.eNumData == OMX_NumericalDataSigned
-                        ? "signed" : "unsigned");
-
-                printf("  ePCMMode = %s\n", asString(params.ePCMMode));
-            } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
-                OMX_AUDIO_PARAM_AMRTYPE amr;
-                InitOMXParams(&amr);
-                amr.nPortIndex = portIndex;
-
-                err = mOMX->getParameter(
-                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
-                CHECK_EQ(err, (status_t)OK);
-
-                printf("  nChannels = %" PRIu32 "\n", amr.nChannels);
-                printf("  eAMRBandMode = %s\n",
-                        asString(amr.eAMRBandMode));
-                printf("  eAMRFrameFormat = %s\n",
-                        asString(amr.eAMRFrameFormat));
-            }
-
-            break;
-        }
-
-        default:
-        {
-            printf("  // Unknown\n");
-            break;
-        }
-    }
-
-    printf("}\n");
-}
-
-status_t OMXCodec::initNativeWindow() {
-    // Enable use of a GraphicBuffer as the output for this node.  This must
-    // happen before getting the IndexParamPortDefinition parameter because it
-    // will affect the pixel format that the node reports.
-    status_t err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
-    if (err != 0) {
-        return err;
-    }
-
-    return OK;
-}
-
-void OMXCodec::initNativeWindowCrop() {
-    int32_t left, top, right, bottom;
-
-    CHECK(mOutputFormat->findRect(
-                        kKeyCropRect,
-                        &left, &top, &right, &bottom));
-
-    android_native_rect_t crop;
-    crop.left = left;
-    crop.top = top;
-    crop.right = right + 1;
-    crop.bottom = bottom + 1;
-
-    // We'll ignore any errors here, if the surface is
-    // already invalid, we'll know soon enough.
-    native_window_set_crop(mNativeWindow.get(), &crop);
-}
-
-void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
-    mOutputFormat = new MetaData;
-    mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
-    if (mIsEncoder) {
-        int32_t timeScale;
-        if (inputFormat->findInt32(kKeyTimeScale, &timeScale)) {
-            mOutputFormat->setInt32(kKeyTimeScale, timeScale);
-        }
-    }
-
-    OMX_PARAM_PORTDEFINITIONTYPE def;
-    InitOMXParams(&def);
-    def.nPortIndex = kPortIndexOutput;
-
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, (status_t)OK);
-
-    switch (def.eDomain) {
-        case OMX_PortDomainImage:
-        {
-            OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
-            CHECK_EQ((int)imageDef->eCompressionFormat,
-                     (int)OMX_IMAGE_CodingUnused);
-
-            mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
-            mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
-            mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
-            mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
-            break;
-        }
-
-        case OMX_PortDomainAudio:
-        {
-            OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
-
-            if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
-                OMX_AUDIO_PARAM_PCMMODETYPE params;
-                InitOMXParams(&params);
-                params.nPortIndex = kPortIndexOutput;
-
-                err = mOMX->getParameter(
-                        mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
-                CHECK_EQ(err, (status_t)OK);
-
-                CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
-                CHECK_EQ(params.nBitPerSample, 16u);
-                CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
-
-                int32_t numChannels, sampleRate;
-                inputFormat->findInt32(kKeyChannelCount, &numChannels);
-                inputFormat->findInt32(kKeySampleRate, &sampleRate);
-
-                if ((OMX_U32)numChannels != params.nChannels) {
-                    ALOGV("Codec outputs a different number of channels than "
-                         "the input stream contains (contains %d channels, "
-                         "codec outputs %u channels).",
-                         numChannels, params.nChannels);
-                }
-
-                if (sampleRate != (int32_t)params.nSamplingRate) {
-                    ALOGV("Codec outputs at different sampling rate than "
-                         "what the input stream contains (contains data at "
-                         "%d Hz, codec outputs %u Hz)",
-                         sampleRate, params.nSamplingRate);
-                }
-
-                mOutputFormat->setCString(
-                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
-
-                // Use the codec-advertised number of channels, as some
-                // codecs appear to output stereo even if the input data is
-                // mono. If we know the codec lies about this information,
-                // use the actual number of channels instead.
-                mOutputFormat->setInt32(
-                        kKeyChannelCount,
-                        (mQuirks & kDecoderLiesAboutNumberOfChannels)
-                            ? numChannels : params.nChannels);
-
-                mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate);
-            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
-                OMX_AUDIO_PARAM_AMRTYPE amr;
-                InitOMXParams(&amr);
-                amr.nPortIndex = kPortIndexOutput;
-
-                err = mOMX->getParameter(
-                        mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
-                CHECK_EQ(err, (status_t)OK);
-
-                CHECK_EQ(amr.nChannels, 1u);
-                mOutputFormat->setInt32(kKeyChannelCount, 1);
-
-                if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
-                    && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
-                    mOutputFormat->setCString(
-                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
-                    mOutputFormat->setInt32(kKeySampleRate, 8000);
-                } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
-                            && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
-                    mOutputFormat->setCString(
-                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
-                    mOutputFormat->setInt32(kKeySampleRate, 16000);
-                } else {
-                    CHECK(!"Unknown AMR band mode.");
-                }
-            } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
-                mOutputFormat->setCString(
-                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
-                int32_t numChannels, sampleRate, bitRate;
-                inputFormat->findInt32(kKeyChannelCount, &numChannels);
-                inputFormat->findInt32(kKeySampleRate, &sampleRate);
-                inputFormat->findInt32(kKeyBitRate, &bitRate);
-                mOutputFormat->setInt32(kKeyChannelCount, numChannels);
-                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
-                mOutputFormat->setInt32(kKeyBitRate, bitRate);
-            } else if (audio_def->eEncoding ==
-                    (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidAC3) {
-                mOutputFormat->setCString(
-                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
-                int32_t numChannels, sampleRate, bitRate;
-                inputFormat->findInt32(kKeyChannelCount, &numChannels);
-                inputFormat->findInt32(kKeySampleRate, &sampleRate);
-                inputFormat->findInt32(kKeyBitRate, &bitRate);
-                mOutputFormat->setInt32(kKeyChannelCount, numChannels);
-                mOutputFormat->setInt32(kKeySampleRate, sampleRate);
-                mOutputFormat->setInt32(kKeyBitRate, bitRate);
-            } else {
-                CHECK(!"Should not be here. Unknown audio encoding.");
-            }
-            break;
-        }
-
-        case OMX_PortDomainVideo:
-        {
-            OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
-
-            if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
-                mOutputFormat->setCString(
-                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
-            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
-                mOutputFormat->setCString(
-                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
-            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
-                mOutputFormat->setCString(
-                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
-            } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
-                mOutputFormat->setCString(
-                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
-            } else {
-                CHECK(!"Unknown compression format.");
-            }
-
-            mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth);
-            mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight);
-            mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat);
-
-            if (!mIsEncoder) {
-                OMX_CONFIG_RECTTYPE rect;
-                InitOMXParams(&rect);
-                rect.nPortIndex = kPortIndexOutput;
-                status_t err =
-                        mOMX->getConfig(
-                            mNode, OMX_IndexConfigCommonOutputCrop,
-                            &rect, sizeof(rect));
-
-                CODEC_LOGI("video dimensions are %u x %u",
-                        video_def->nFrameWidth, video_def->nFrameHeight);
-
-                if (err == OK) {
-                    CHECK_GE(rect.nLeft, 0);
-                    CHECK_GE(rect.nTop, 0);
-                    CHECK_GE(rect.nWidth, 0u);
-                    CHECK_GE(rect.nHeight, 0u);
-                    CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth);
-                    CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight);
-
-                    mOutputFormat->setRect(
-                            kKeyCropRect,
-                            rect.nLeft,
-                            rect.nTop,
-                            rect.nLeft + rect.nWidth - 1,
-                            rect.nTop + rect.nHeight - 1);
-
-                    CODEC_LOGI("Crop rect is %u x %u @ (%d, %d)",
-                            rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop);
-                } else {
-                    mOutputFormat->setRect(
-                            kKeyCropRect,
-                            0, 0,
-                            video_def->nFrameWidth - 1,
-                            video_def->nFrameHeight - 1);
-                }
-
-                if (mNativeWindow != NULL) {
-                     initNativeWindowCrop();
-                }
-            }
-            break;
-        }
-
-        default:
-        {
-            CHECK(!"should not be here, neither audio nor video.");
-            break;
-        }
-    }
-
-    // If the input format contains rotation information, flag the output
-    // format accordingly.
-
-    int32_t rotationDegrees;
-    if (mSource->getFormat()->findInt32(kKeyRotation, &rotationDegrees)) {
-        mOutputFormat->setInt32(kKeyRotation, rotationDegrees);
-    }
-}
-
-status_t OMXCodec::pause() {
-    Mutex::Autolock autoLock(mLock);
-
-    mPaused = true;
-
-    return OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-status_t QueryCodecs(
-        const sp<IOMX> &omx,
-        const char *mime, bool queryDecoders, bool hwCodecOnly,
-        Vector<CodecCapabilities> *results) {
-    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
-    results->clear();
-
-    OMXCodec::findMatchingCodecs(mime,
-            !queryDecoders /*createEncoder*/,
-            NULL /*matchComponentName*/,
-            hwCodecOnly ? OMXCodec::kHardwareCodecsOnly : 0 /*flags*/,
-            &matchingCodecs);
-
-    for (size_t c = 0; c < matchingCodecs.size(); c++) {
-        const char *componentName = matchingCodecs.itemAt(c).mName.string();
-
-        results->push();
-        CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
-
-        status_t err =
-            QueryCodec(omx, componentName, mime, !queryDecoders, caps);
-
-        if (err != OK) {
-            results->removeAt(results->size() - 1);
-        }
-    }
-
-    return OK;
-}
-
-status_t QueryCodec(
-        const sp<IOMX> &omx,
-        const char *componentName, const char *mime,
-        bool isEncoder,
-        CodecCapabilities *caps) {
-    bool isVideo = !strncasecmp(mime, "video/", 6);
-
-    sp<OMXCodecObserver> observer = new OMXCodecObserver;
-    IOMX::node_id node;
-    status_t err = omx->allocateNode(componentName, observer, &node);
-
-    if (err != OK) {
-        return err;
-    }
-
-    OMXCodec::setComponentRole(omx, node, isEncoder, mime);
-
-    caps->mFlags = 0;
-    caps->mComponentName = componentName;
-
-    if (isVideo) {
-        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
-        InitOMXParams(&param);
-
-        param.nPortIndex = !isEncoder ? 0 : 1;
-
-        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
-            err = omx->getParameter(
-                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
-                    &param, sizeof(param));
-
-            if (err != OK) {
-                break;
-            }
-
-            CodecProfileLevel profileLevel;
-            profileLevel.mProfile = param.eProfile;
-            profileLevel.mLevel = param.eLevel;
-
-            caps->mProfileLevels.push(profileLevel);
-        }
-
-        // Color format query
-        // return colors in the order reported by the OMX component
-        // prefix "flexible" standard ones with the flexible equivalent
-        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
-        InitOMXParams(&portFormat);
-        portFormat.nPortIndex = !isEncoder ? 1 : 0;
-        for (portFormat.nIndex = 0;; ++portFormat.nIndex)  {
-            err = omx->getParameter(
-                    node, OMX_IndexParamVideoPortFormat,
-                    &portFormat, sizeof(portFormat));
-            if (err != OK) {
-                break;
-            }
-
-            OMX_U32 flexibleEquivalent;
-            if (ACodec::isFlexibleColorFormat(
-                        omx, node, portFormat.eColorFormat, false /* usingNativeWindow */,
-                        &flexibleEquivalent)) {
-                bool marked = false;
-                for (size_t i = 0; i < caps->mColorFormats.size(); i++) {
-                    if (caps->mColorFormats.itemAt(i) == flexibleEquivalent) {
-                        marked = true;
-                        break;
-                    }
-                }
-                if (!marked) {
-                    caps->mColorFormats.push(flexibleEquivalent);
-                }
-            }
-            caps->mColorFormats.push(portFormat.eColorFormat);
-        }
-    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
-        // More audio codecs if they have profiles.
-        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
-        InitOMXParams(&param);
-        param.nPortIndex = isEncoder ? 1 : 0;
-        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
-            err = omx->getParameter(
-                    node, (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
-                    &param, sizeof(param));
-
-            if (err != OK) {
-                break;
-            }
-
-            CodecProfileLevel profileLevel;
-            profileLevel.mProfile = param.eProfile;
-            // For audio, level is ignored.
-            profileLevel.mLevel = 0;
-
-            caps->mProfileLevels.push(profileLevel);
-        }
-
-        // NOTE: Without Android extensions, OMX does not provide a way to query
-        // AAC profile support
-        if (param.nProfileIndex == 0) {
-            ALOGW("component %s doesn't support profile query.", componentName);
-        }
-    }
-
-    if (isVideo && !isEncoder) {
-        if (omx->storeMetaDataInBuffers(
-                    node, 1 /* port index */, OMX_TRUE) == OK ||
-            omx->prepareForAdaptivePlayback(
-                    node, 1 /* port index */, OMX_TRUE,
-                    1280 /* width */, 720 /* height */) == OK) {
-            caps->mFlags |= CodecCapabilities::kFlagSupportsAdaptivePlayback;
-        }
-    }
-
-    CHECK_EQ(omx->freeNode(node), (status_t)OK);
-
-    return OK;
-}
-
-status_t QueryCodecs(
-        const sp<IOMX> &omx,
-        const char *mimeType, bool queryDecoders,
-        Vector<CodecCapabilities> *results) {
-    return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results);
-}
-
-}  // namespace android
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index 7fafb6f..6106a93 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -17,6 +17,8 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "SoftVPX"
 #include <utils/Log.h>
+#include <utils/misc.h>
+#include "OMX_VideoExt.h"
 
 #include "SoftVPX.h"
 
@@ -26,6 +28,11 @@
 
 namespace android {
 
+// Only need to declare the highest supported profile and level here.
+static const CodecProfileLevel kVP9ProfileLevels[] = {
+    { OMX_VIDEO_VP9Profile0, OMX_VIDEO_VP9Level5  },
+};
+
 SoftVPX::SoftVPX(
         const char *name,
         const char *componentRole,
@@ -35,7 +42,8 @@
         OMX_COMPONENTTYPE **component)
     : SoftVideoDecoderOMXComponent(
             name, componentRole, codingType,
-            NULL /* profileLevels */, 0 /* numProfileLevels */,
+            codingType == OMX_VIDEO_CodingVP8 ? NULL : kVP9ProfileLevels,
+            codingType == OMX_VIDEO_CodingVP8 ?  0 : NELEM(kVP9ProfileLevels),
             320 /* width */, 240 /* height */, callbacks, appData, component),
       mMode(codingType == OMX_VIDEO_CodingVP8 ? MODE_VP8 : MODE_VP9),
       mEOSStatus(INPUT_DATA_AVAILABLE),
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index e7c4f6d..4c27360 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -62,8 +62,8 @@
     virtual status_t getState(
             node_id node, OMX_STATETYPE* state);
 
-    virtual status_t enableGraphicBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable);
+    virtual status_t enableNativeBuffers(
+            node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable);
 
     virtual status_t getGraphicBufferUsage(
             node_id node, OMX_U32 port_index, OMX_U32* usage);
@@ -107,9 +107,9 @@
 
     virtual status_t signalEndOfInputStream(node_id node);
 
-    virtual status_t allocateBuffer(
+    virtual status_t allocateSecureBuffer(
             node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer, void **buffer_data);
+            buffer_id *buffer, void **buffer_data, native_handle_t **native_handle);
 
     virtual status_t allocateBufferWithBackup(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
@@ -166,13 +166,13 @@
 
     Mutex mLock;
     OMXMaster *mMaster;
-    int32_t mNodeCounter;
+    size_t mNodeCounter;
 
     KeyedVector<wp<IBinder>, OMXNodeInstance *> mLiveNodes;
     KeyedVector<node_id, OMXNodeInstance *> mNodeIDToInstance;
     KeyedVector<node_id, sp<CallbackDispatcher> > mDispatchers;
 
-    node_id makeNodeID(OMXNodeInstance *instance);
+    node_id makeNodeID_l(OMXNodeInstance *instance);
     OMXNodeInstance *findInstance(node_id node);
     sp<CallbackDispatcher> findDispatcher(node_id node);
 
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index e5fb45b..732894c 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -54,7 +54,7 @@
 
     status_t getState(OMX_STATETYPE* state);
 
-    status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable);
+    status_t enableNativeBuffers(OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable);
 
     status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage);
 
@@ -95,9 +95,9 @@
 
     status_t signalEndOfInputStream();
 
-    status_t allocateBuffer(
+    status_t allocateSecureBuffer(
             OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
-            void **buffer_data);
+            void **buffer_data, native_handle_t **native_handle);
 
     status_t allocateBufferWithBackup(
             OMX_U32 portIndex, const sp<IMemory> &params,
@@ -165,7 +165,15 @@
     uint32_t mBufferIDCount;
     KeyedVector<OMX::buffer_id, OMX_BUFFERHEADERTYPE *> mBufferIDToBufferHeader;
     KeyedVector<OMX_BUFFERHEADERTYPE *, OMX::buffer_id> mBufferHeaderToBufferID;
+
+    // metadata and secure buffer type tracking
     MetadataBufferType mMetadataType[2];
+    enum SecureBufferType {
+        kSecureBufferTypeUnknown,
+        kSecureBufferTypeOpaque,
+        kSecureBufferTypeNativeHandle,
+    };
+    SecureBufferType mSecureBufferType[2];
 
     // For debug support
     char *mName;
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 539b4e3..a20028b 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -38,6 +38,9 @@
 
 namespace android {
 
+// node ids are created by concatenating the pid with a 16-bit counter
+static size_t kMaxNodeInstances = (1 << 16);
+
 ////////////////////////////////////////////////////////////////////////////////
 
 // This provides the underlying Thread used by CallbackDispatcher.
@@ -237,6 +240,11 @@
 
     *node = 0;
 
+    if (mNodeIDToInstance.size() == kMaxNodeInstances) {
+        // all possible node IDs are in use
+        return NO_MEMORY;
+    }
+
     OMXNodeInstance *instance = new OMXNodeInstance(this, observer, name);
 
     OMX_COMPONENTTYPE *handle;
@@ -252,7 +260,7 @@
         return StatusFromOMXError(err);
     }
 
-    *node = makeNodeID(instance);
+    *node = makeNodeID_l(instance);
     mDispatchers.add(*node, new CallbackDispatcher(instance));
 
     instance->setHandle(*node, handle);
@@ -372,15 +380,15 @@
             state);
 }
 
-status_t OMX::enableGraphicBuffers(
-        node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+status_t OMX::enableNativeBuffers(
+        node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
     OMXNodeInstance *instance = findInstance(node);
 
     if (instance == NULL) {
         return NAME_NOT_FOUND;
     }
 
-    return instance->enableGraphicBuffers(port_index, enable);
+    return instance->enableNativeBuffers(port_index, graphic, enable);
 }
 
 status_t OMX::getGraphicBufferUsage(
@@ -513,17 +521,17 @@
     return instance->signalEndOfInputStream();
 }
 
-status_t OMX::allocateBuffer(
+status_t OMX::allocateSecureBuffer(
         node_id node, OMX_U32 port_index, size_t size,
-        buffer_id *buffer, void **buffer_data) {
+        buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
     OMXNodeInstance *instance = findInstance(node);
 
     if (instance == NULL) {
         return NAME_NOT_FOUND;
     }
 
-    return instance->allocateBuffer(
-            port_index, size, buffer, buffer_data);
+    return instance->allocateSecureBuffer(
+            port_index, size, buffer, buffer_data, native_handle);
 }
 
 status_t OMX::allocateBufferWithBackup(
@@ -690,10 +698,17 @@
     return OMX_ErrorNone;
 }
 
-OMX::node_id OMX::makeNodeID(OMXNodeInstance *instance) {
+OMX::node_id OMX::makeNodeID_l(OMXNodeInstance *instance) {
     // mLock is already held.
 
-    node_id node = (node_id)++mNodeCounter;
+    node_id prefix = node_id(getpid() << 16);
+    node_id node = 0;
+    do  {
+        if (++mNodeCounter >= kMaxNodeInstances) {
+            mNodeCounter = 0; // OK to use because we're combining with the pid
+        }
+        node = node_id(prefix | mNodeCounter);
+    } while (mNodeIDToInstance.indexOfKey(node) >= 0);
     mNodeIDToInstance.add(node, instance);
 
     return node;
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 9ae238a..a8c55fa 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -29,6 +29,7 @@
 #include <OMX_AsString.h>
 
 #include <binder/IMemory.h>
+#include <cutils/properties.h>
 #include <gui/BufferQueue.h>
 #include <HardwareAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -203,6 +204,8 @@
     mDebugLevelBumpPendingBuffers[1] = 0;
     mMetadataType[0] = kMetadataBufferTypeInvalid;
     mMetadataType[1] = kMetadataBufferTypeInvalid;
+    mSecureBufferType[0] = kSecureBufferTypeUnknown;
+    mSecureBufferType[1] = kSecureBufferTypeUnknown;
     mIsSecure = AString(name).endsWith(".secure");
 }
 
@@ -453,12 +456,14 @@
     return StatusFromOMXError(err);
 }
 
-status_t OMXNodeInstance::enableGraphicBuffers(
-        OMX_U32 portIndex, OMX_BOOL enable) {
+status_t OMXNodeInstance::enableNativeBuffers(
+        OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable) {
     Mutex::Autolock autoLock(mLock);
-    CLOG_CONFIG(enableGraphicBuffers, "%s:%u, %d", portString(portIndex), portIndex, enable);
+    CLOG_CONFIG(enableNativeBuffers, "%s:%u%s, %d", portString(portIndex), portIndex,
+                graphic ? ", graphic" : "", enable);
     OMX_STRING name = const_cast<OMX_STRING>(
-            "OMX.google.android.index.enableAndroidNativeBuffers");
+            graphic ? "OMX.google.android.index.enableAndroidNativeBuffers"
+                    : "OMX.google.android.index.allocateNativeHandle");
 
     OMX_INDEXTYPE index;
     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
@@ -476,6 +481,25 @@
     err = OMX_SetParameter(mHandle, index, &params);
     CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,
             portString(portIndex), portIndex, enable);
+    if (!graphic) {
+        if (err == OK) {
+            mSecureBufferType[portIndex] =
+                enable ? kSecureBufferTypeNativeHandle : kSecureBufferTypeOpaque;
+        } else if (mSecureBufferType[portIndex] == kSecureBufferTypeUnknown) {
+
+            // BEGIN ALTERNATE SIGNALING FOR USING NATIVE HANDLES
+            char value[PROPERTY_VALUE_MAX];
+            if (property_get("media.mediadrmservice.enable", value, NULL)
+                    && (!strcmp("1", value) || !strcasecmp("true", value))) {
+                CLOG_CONFIG(enableNativeBuffers, "system property override: using native-handles");
+                mSecureBufferType[portIndex] = kSecureBufferTypeNativeHandle;
+                return OK;
+            }
+            // END ALTERNATE SIGNALING FOR USING NATIVE HANDLES
+
+            mSecureBufferType[portIndex] = kSecureBufferTypeOpaque;
+        }
+    }
     return StatusFromOMXError(err);
 }
 
@@ -996,10 +1020,10 @@
     return bufferSource->signalEndOfInputStream();
 }
 
-status_t OMXNodeInstance::allocateBuffer(
+status_t OMXNodeInstance::allocateSecureBuffer(
         OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
-        void **buffer_data) {
-    if (buffer == NULL || buffer_data == NULL) {
+        void **buffer_data, native_handle_t **native_handle) {
+    if (buffer == NULL || buffer_data == NULL || native_handle == NULL) {
         ALOGE("b/25884056");
         return BAD_VALUE;
     }
@@ -1026,7 +1050,13 @@
     CHECK_EQ(header->pAppPrivate, buffer_meta);
 
     *buffer = makeBufferID(header);
-    *buffer_data = header->pBuffer;
+    if (mSecureBufferType[portIndex] == kSecureBufferTypeNativeHandle) {
+        *buffer_data = NULL;
+        *native_handle = (native_handle_t *)header->pBuffer;
+    } else {
+        *buffer_data = header->pBuffer;
+        *native_handle = NULL;
+    }
 
     addActiveBuffer(portIndex, *buffer);
 
@@ -1034,7 +1064,8 @@
     if (bufferSource != NULL && portIndex == kPortIndexInput) {
         bufferSource->addCodecBuffer(header);
     }
-    CLOG_BUFFER(allocateBuffer, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p", size, *buffer_data));
+    CLOG_BUFFER(allocateSecureBuffer, NEW_BUFFER_FMT(
+            *buffer, portIndex, "%zu@%p:%p", size, *buffer_data, *native_handle));
 
     return OK;
 }
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 6e21c14..c0ccb35 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -37,7 +37,7 @@
 #include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MetaData.h>
-#include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/SimpleDecodingSource.h>
 
 #define DEFAULT_TIMEOUT         500000
 
@@ -576,9 +576,8 @@
 
     CHECK_EQ(seekSource->start(), (status_t)OK);
 
-    sp<IMediaSource> codec = OMXCodec::Create(
-            mOMX, source->getFormat(), false /* createEncoder */,
-            source, componentName);
+    sp<IMediaSource> codec = SimpleDecodingSource::Create(
+            source, 0 /* flags */, NULL /* nativeWindow */, componentName);
 
     CHECK(codec != NULL);
 
diff --git a/media/ndk/Android.mk b/media/ndk/Android.mk
index 6546f14..8dbb291 100644
--- a/media/ndk/Android.mk
+++ b/media/ndk/Android.mk
@@ -47,6 +47,7 @@
     libstagefright_foundation \
     liblog \
     libutils \
+    libcutils \
     libandroid_runtime \
     libbinder \
     libgui \
diff --git a/media/ndk/NdkMediaCrypto.cpp b/media/ndk/NdkMediaCrypto.cpp
index 1cc2f1a..af8ffea 100644
--- a/media/ndk/NdkMediaCrypto.cpp
+++ b/media/ndk/NdkMediaCrypto.cpp
@@ -23,10 +23,12 @@
 #include "NdkMediaFormatPriv.h"
 
 
+#include <cutils/properties.h>
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
 #include <binder/IServiceManager.h>
 #include <media/ICrypto.h>
+#include <media/IMediaDrmService.h>
 #include <media/IMediaPlayerService.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
@@ -46,19 +48,30 @@
 
 static sp<ICrypto> makeCrypto() {
     sp<IServiceManager> sm = defaultServiceManager();
+    sp<ICrypto> crypto;
 
-    sp<IBinder> binder =
-        sm->getService(String16("media.player"));
-
-    sp<IMediaPlayerService> service =
-        interface_cast<IMediaPlayerService>(binder);
-
-    if (service == NULL) {
-        return NULL;
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("media.mediadrmservice.enable", value, NULL)
+        && (!strcmp("1", value) || !strcasecmp("true", value))) {
+        sp<IBinder> binder =
+            sm->getService(String16("media.drm"));
+        sp<IMediaDrmService> service =
+            interface_cast<IMediaDrmService>(binder);
+        if (service == NULL) {
+            return NULL;
+        }
+        crypto = service->makeCrypto();
+    } else {
+        sp<IBinder> binder =
+            sm->getService(String16("media.player"));
+        sp<IMediaPlayerService> service =
+            interface_cast<IMediaPlayerService>(binder);
+        if (service == NULL) {
+            return NULL;
+        }
+        crypto = service->makeCrypto();
     }
 
-    sp<ICrypto> crypto = service->makeCrypto();
-
     if (crypto == NULL || (crypto->initCheck() != OK && crypto->initCheck() != NO_INIT)) {
         return NULL;
     }
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index 83a5ba1..ea47d57 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -19,6 +19,7 @@
 
 #include "NdkMediaDrm.h"
 
+#include <cutils/properties.h>
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
 #include <gui/Surface.h>
@@ -27,6 +28,7 @@
 #include <media/IDrmClient.h>
 #include <media/stagefright/MediaErrors.h>
 #include <binder/IServiceManager.h>
+#include <media/IMediaDrmService.h>
 #include <media/IMediaPlayerService.h>
 #include <ndk/NdkMediaCrypto.h>
 
@@ -148,19 +150,30 @@
 
 static sp<IDrm> CreateDrm() {
     sp<IServiceManager> sm = defaultServiceManager();
+    sp<IDrm> drm;
 
-    sp<IBinder> binder =
-        sm->getService(String16("media.player"));
-
-    sp<IMediaPlayerService> service =
-        interface_cast<IMediaPlayerService>(binder);
-
-    if (service == NULL) {
-        return NULL;
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("media.mediadrmservice.enable", value, NULL)
+        && (!strcmp("1", value) || !strcasecmp("true", value))) {
+        sp<IBinder> binder =
+            sm->getService(String16("media.drm"));
+        sp<IMediaDrmService> service =
+            interface_cast<IMediaDrmService>(binder);
+        if (service == NULL) {
+            return NULL;
+        }
+        drm = service->makeDrm();
+    } else {
+        sp<IBinder> binder =
+            sm->getService(String16("media.player"));
+        sp<IMediaPlayerService> service =
+            interface_cast<IMediaPlayerService>(binder);
+        if (service == NULL) {
+            return NULL;
+        }
+        drm = service->makeDrm();
     }
 
-    sp<IDrm> drm = service->makeDrm();
-
     if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
         return NULL;
     }
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index fe3cc53..c81bbf9 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -89,7 +89,6 @@
     // ExtendedAudioBufferProvider interface
     virtual size_t framesReady() const;
     virtual size_t framesReleased() const;
-    virtual void onTimestamp(const AudioTimestamp &timestamp);
 
     bool isPausing() const { return mState == PAUSING; }
     bool isPaused() const { return mState == PAUSED; }
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 1a48e07..b719046 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -596,11 +596,6 @@
     return mAudioTrackServerProxy->framesReleased();
 }
 
-void AudioFlinger::PlaybackThread::Track::onTimestamp(const AudioTimestamp &timestamp)
-{
-    mAudioTrackServerProxy->setTimestamp(timestamp);
-}
-
 // Don't call for fast tracks; the framesReady() could result in priority inversion
 bool AudioFlinger::PlaybackThread::Track::isReady() const {
     if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
@@ -863,7 +858,7 @@
 
 status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
 {
-    // FastTrack timestamps are read through SSQ
+    // Client should implement this using SSQ; the unpresented frame count in latch is irrelevant
     if (isFastTrack()) {
         return INVALID_OPERATION;
     }
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index e3ee4e5..18acb23 100755
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -126,3 +126,18 @@
     }
     return 0;
 }
+
+/* Indicates if audio formats are equivalent when considering a match between
+ * audio HAL supported formats and client requested formats
+ */
+static inline bool audio_formats_match(audio_format_t format1,
+                                       audio_format_t format2)
+{
+    if (audio_is_linear_pcm(format1) &&
+            (audio_bytes_per_sample(format1) > 2) &&
+            audio_is_linear_pcm(format2) &&
+            (audio_bytes_per_sample(format2) > 2)) {
+        return true;
+    }
+    return format1 == format2;
+}
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 0da3aea..e19a8ee 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -110,6 +110,12 @@
 
     static int compareFormats(audio_format_t format1, audio_format_t format2);
 
+    // Used to select an audio HAL output stream with a sample format providing the
+    // less degradation for a given AudioTrack sample format.
+    static bool isBetterFormatMatch(audio_format_t newFormat,
+                                        audio_format_t currentFormat,
+                                        audio_format_t targetFormat);
+
     audio_module_handle_t getModuleHandle() const;
     uint32_t getModuleVersion() const;
     const char *getModuleName() const;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index 191439e..bda59ad 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -268,6 +268,32 @@
     return index1 - index2;
 }
 
+bool AudioPort::isBetterFormatMatch(audio_format_t newFormat,
+                                    audio_format_t currentFormat,
+                                    audio_format_t targetFormat)
+{
+    if (newFormat == currentFormat) {
+        return false;
+    }
+    if (currentFormat == AUDIO_FORMAT_INVALID) {
+        return true;
+    }
+    if (newFormat == targetFormat) {
+        return true;
+    }
+    int currentDiffBytes = (int)audio_bytes_per_sample(targetFormat) -
+            audio_bytes_per_sample(currentFormat);
+    int newDiffBytes = (int)audio_bytes_per_sample(targetFormat) -
+            audio_bytes_per_sample(newFormat);
+
+    if (abs(newDiffBytes) < abs(currentDiffBytes)) {
+        return true;
+    } else if (abs(newDiffBytes) == abs(currentDiffBytes)) {
+        return (newDiffBytes >= 0);
+    }
+    return false;
+}
+
 void AudioPort::pickAudioProfile(uint32_t &samplingRate,
                                  audio_channel_mask_t &channelMask,
                                  audio_format_t &format) const
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
index c599665..961072e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
@@ -31,7 +31,7 @@
 status_t AudioProfile::checkExact(uint32_t samplingRate, audio_channel_mask_t channelMask,
                                   audio_format_t format) const
 {
-    if (format == mFormat &&
+    if (audio_formats_match(format, mFormat) &&
             (mChannelMasks.isEmpty() || supportsChannels(channelMask)) &&
             (mSamplingRates.isEmpty() || supportsRate(samplingRate))) {
         return NO_ERROR;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 8bb49fa..bf68d46 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -876,7 +876,7 @@
                 outputDesc = desc;
                 // reuse direct output if currently open and configured with same parameters
                 if ((samplingRate == outputDesc->mSamplingRate) &&
-                        (format == outputDesc->mFormat) &&
+                        audio_formats_match(format, outputDesc->mFormat) &&
                         (channelMask == outputDesc->mChannelMask)) {
                     outputDesc->mDirectOpenCount++;
                     ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
@@ -927,7 +927,7 @@
         // only accept an output with the requested parameters
         if (status != NO_ERROR ||
             (samplingRate != 0 && samplingRate != config.sample_rate) ||
-            (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
+            (format != AUDIO_FORMAT_DEFAULT && !audio_formats_match(format, config.format)) ||
             (channelMask != 0 && channelMask != config.channel_mask)) {
             ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
                     "format %d %d, channelMask %04x %04x", output, samplingRate,
@@ -992,8 +992,9 @@
     // devices (the list was previously build by getOutputsForDevice()).
     // The priority is as follows:
     // 1: the output with the highest number of requested policy flags
-    // 2: the primary output
-    // 3: the first output in the list
+    // 2: the output with the bit depth the closest to the requested one
+    // 3: the primary output
+    // 4: the first output in the list
 
     if (outputs.size() == 0) {
         return 0;
@@ -1003,8 +1004,11 @@
     }
 
     int maxCommonFlags = 0;
-    audio_io_handle_t outputFlags = 0;
-    audio_io_handle_t outputPrimary = 0;
+    audio_io_handle_t outputForFlags = 0;
+    audio_io_handle_t outputForPrimary = 0;
+    audio_io_handle_t outputForFormat = 0;
+    audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
+    audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;
 
     for (size_t i = 0; i < outputs.size(); i++) {
         sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
@@ -1012,31 +1016,48 @@
             // if a valid format is specified, skip output if not compatible
             if (format != AUDIO_FORMAT_INVALID) {
                 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
-                    if (format != outputDesc->mFormat) {
+                    if (!audio_formats_match(format, outputDesc->mFormat)) {
                         continue;
                     }
                 } else if (!audio_is_linear_pcm(format)) {
                     continue;
                 }
+                if (AudioPort::isBetterFormatMatch(
+                        outputDesc->mFormat, bestFormat, format)) {
+                    outputForFormat = outputs[i];
+                    bestFormat = outputDesc->mFormat;
+                }
             }
 
             int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags);
-            if (commonFlags > maxCommonFlags) {
-                outputFlags = outputs[i];
-                maxCommonFlags = commonFlags;
+            if (commonFlags >= maxCommonFlags) {
+                if (commonFlags == maxCommonFlags) {
+                    if (AudioPort::isBetterFormatMatch(
+                            outputDesc->mFormat, bestFormatForFlags, format)) {
+                        outputForFlags = outputs[i];
+                        bestFormatForFlags = outputDesc->mFormat;
+                    }
+                } else {
+                    outputForFlags = outputs[i];
+                    maxCommonFlags = commonFlags;
+                    bestFormatForFlags = outputDesc->mFormat;
+                }
                 ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
             }
             if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
-                outputPrimary = outputs[i];
+                outputForPrimary = outputs[i];
             }
         }
     }
 
-    if (outputFlags != 0) {
-        return outputFlags;
+    if (outputForFlags != 0) {
+        return outputForFlags;
     }
-    if (outputPrimary != 0) {
-        return outputPrimary;
+    if (outputForFormat != 0) {
+        return outputForFormat;
+    }
+    if (outputForPrimary != 0) {
+        return outputForPrimary;
     }
 
     return outputs[0];
@@ -1509,7 +1530,7 @@
             // and current input properties are not exactly as requested.
             if ((desc->mSamplingRate != samplingRate ||
                     desc->mChannelMask != channelMask ||
-                    desc->mFormat != format) &&
+                    !audio_formats_match(desc->mFormat, format)) &&
                     (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) <
                      source_priority(inputSource))) {
                 ALOGV("%s: ", __FUNCTION__);
@@ -1544,7 +1565,7 @@
     // only accept input with the exact requested set of parameters
     if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE ||
         (profileSamplingRate != config.sample_rate) ||
-        (profileFormat != config.format) ||
+        !audio_formats_match(profileFormat, config.format) ||
         (profileChannelMask != config.channel_mask)) {
         ALOGW("getInputForAttr() failed opening input: samplingRate %d"
               ", format %d, channelMask %x",
@@ -2200,6 +2221,15 @@
         return false;
     }
 
+    // Check if streaming is off, then only allow offload as of now.
+    // This is a temporary work around until the root cause is fixed in offload
+    // playback path.
+    if (offloadInfo.is_streaming)
+    {
+        ALOGV("isOffloadSupported: is_streaming == true, returning false");
+        return false;
+    }
+
     //TODO: enable audio offloading with video when ready
     const bool allowOffloadWithVideo =
             property_get_bool("audio.offload.video", false /* default_value */);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index b524f61..5f990a9 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -460,7 +460,7 @@
     const int SIZE_OFFSET = 2;
     camera_metadata_ro_entry rawOpaqueSizes =
         mDeviceInfo.find(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
-    int count = rawOpaqueSizes.count;
+    size_t count = rawOpaqueSizes.count;
     if (count == 0 || (count % PER_CONFIGURATION_SIZE)) {
         ALOGE("%s: Camera %d: bad opaque RAW size static metadata length(%d)!",
                 __FUNCTION__, mId, count);
diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
index eefcb44..7414c4c 100644
--- a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
@@ -115,8 +115,7 @@
         Camera3OutputStream(id, CAMERA3_STREAM_BIDIRECTIONAL,
                             width, height,
                             HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-                            HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0),
-        mDepth(bufferCount) {
+                            HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0) {
 
     sp<IGraphicBufferProducer> producer;
     sp<IGraphicBufferConsumer> consumer;
diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.h b/services/camera/libcameraservice/device3/Camera3ZslStream.h
index 5323a49..12369cf 100644
--- a/services/camera/libcameraservice/device3/Camera3ZslStream.h
+++ b/services/camera/libcameraservice/device3/Camera3ZslStream.h
@@ -73,7 +73,6 @@
 
   private:
 
-    int mDepth;
     // Input buffers pending to be queued into HAL
     List<sp<RingBufferConsumer::PinnedBufferItem> > mInputBufferQueue;
     sp<RingBufferConsumer>                          mProducer;
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
new file mode 100644
index 0000000..cc78361
--- /dev/null
+++ b/services/mediadrm/Android.mk
@@ -0,0 +1,42 @@
+# Copyright 2014 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+
+LOCAL_SRC_FILES:= \
+    MediaDrmService.cpp \
+    main_mediadrmserver.cpp
+
+LOCAL_SHARED_LIBRARIES:= \
+    libui \
+    liblog \
+    libutils \
+    libbinder \
+    libcutils \
+    libstagefright \
+    libmediaplayerservice \
+    libmedia \
+
+LOCAL_C_INCLUDES := \
+    frameworks/av/media/libmediaplayerservice \
+
+LOCAL_MODULE:= mediadrmserver
+LOCAL_32_BIT_ONLY := true
+
+LOCAL_INIT_RC := mediadrmserver.rc
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/mediadrm/DrmSessionClientInterface.h b/services/mediadrm/DrmSessionClientInterface.h
new file mode 100644
index 0000000..17faf08
--- /dev/null
+++ b/services/mediadrm/DrmSessionClientInterface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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 DRM_PROXY_INTERFACE_H_
+#define DRM_PROXY_INTERFACE_H_
+
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct DrmSessionClientInterface : public RefBase {
+    virtual bool reclaimSession(const Vector<uint8_t>& sessionId) = 0;
+
+protected:
+    virtual ~DrmSessionClientInterface() {}
+};
+
+}  // namespace android
+
+#endif  // DRM_PROXY_INTERFACE_H_
diff --git a/services/mediadrm/MediaDrmService.cpp b/services/mediadrm/MediaDrmService.cpp
new file mode 100644
index 0000000..36ab8fe
--- /dev/null
+++ b/services/mediadrm/MediaDrmService.cpp
@@ -0,0 +1,45 @@
+/*
+**
+** Copyright 2008, 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.
+*/
+
+// Proxy for media player implementations
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaDrmService"
+#include <utils/Log.h>
+
+#include <binder/IServiceManager.h>
+#include "MediaDrmService.h"
+
+#include "Crypto.h"
+#include "Drm.h"
+
+namespace android {
+
+void MediaDrmService::instantiate() {
+    defaultServiceManager()->addService(
+            String16("media.drm"), new MediaDrmService());
+}
+
+sp<ICrypto> MediaDrmService::makeCrypto() {
+    return new Crypto;
+}
+
+sp<IDrm> MediaDrmService::makeDrm() {
+    return new Drm;
+}
+
+} // namespace android
diff --git a/services/mediadrm/MediaDrmService.h b/services/mediadrm/MediaDrmService.h
new file mode 100644
index 0000000..ecc2da7
--- /dev/null
+++ b/services/mediadrm/MediaDrmService.h
@@ -0,0 +1,48 @@
+/*
+**
+** Copyright 2008, 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_MEDIADRMSERVICE_H
+#define ANDROID_MEDIADRMSERVICE_H
+
+#include <arpa/inet.h>
+
+#include <utils/threads.h>
+
+#include <media/Metadata.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <media/IMediaDrmService.h>
+
+namespace android {
+
+class MediaDrmService : public BnMediaDrmService
+{
+public:
+    static void instantiate();
+
+    // IMediaDrmService interface
+    virtual sp<ICrypto> makeCrypto();
+    virtual sp<IDrm> makeDrm();
+private:
+    MediaDrmService() {}
+    virtual ~MediaDrmService() {}
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_MEDIADRMSERVICE_H
diff --git a/services/mediadrm/main_mediadrmserver.cpp b/services/mediadrm/main_mediadrmserver.cpp
new file mode 100644
index 0000000..4d0b644
--- /dev/null
+++ b/services/mediadrm/main_mediadrmserver.cpp
@@ -0,0 +1,43 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "mediaserver"
+//#define LOG_NDEBUG 0
+
+#include <fcntl.h>
+#include <sys/prctl.h>
+#include <sys/wait.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+#include <cutils/properties.h>
+#include <utils/Log.h>
+#include "MediaDrmService.h"
+
+using namespace android;
+
+int main(int argc __unused, char** argv)
+{
+    signal(SIGPIPE, SIG_IGN);
+
+    sp<ProcessState> proc(ProcessState::self());
+    sp<IServiceManager> sm = defaultServiceManager();
+    ALOGI("ServiceManager: %p", sm.get());
+    MediaDrmService::instantiate();
+    ProcessState::self()->startThreadPool();
+    IPCThreadState::self()->joinThreadPool();
+}
diff --git a/services/mediadrm/mediadrmserver.rc b/services/mediadrm/mediadrmserver.rc
new file mode 100644
index 0000000..c22ec7c
--- /dev/null
+++ b/services/mediadrm/mediadrmserver.rc
@@ -0,0 +1,5 @@
+service mediadrm /system/bin/mediadrmserver
+    class main
+    user mediadrm
+    group drmrpc
+    ioprio rt 4
diff --git a/services/mediadrm/tests/Android.mk b/services/mediadrm/tests/Android.mk
new file mode 100644
index 0000000..8cbf782
--- /dev/null
+++ b/services/mediadrm/tests/Android.mk
@@ -0,0 +1,27 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := DrmSessionManager_test
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+	DrmSessionManager_test.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+	liblog \
+	libmediaplayerservice \
+	libutils \
+
+LOCAL_C_INCLUDES := \
+	frameworks/av/include \
+	frameworks/av/media/libmediaplayerservice \
+
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
+
+LOCAL_32_BIT_ONLY := true
+
+include $(BUILD_NATIVE_TEST)
+
diff --git a/services/mediadrm/tests/DrmSessionManager_test.cpp b/services/mediadrm/tests/DrmSessionManager_test.cpp
new file mode 100644
index 0000000..de350a1
--- /dev/null
+++ b/services/mediadrm/tests/DrmSessionManager_test.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2015 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 "DrmSessionManager_test"
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+
+#include "Drm.h"
+#include "DrmSessionClientInterface.h"
+#include "DrmSessionManager.h"
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/ProcessInfoInterface.h>
+
+namespace android {
+
+struct FakeProcessInfo : public ProcessInfoInterface {
+    FakeProcessInfo() {}
+    virtual ~FakeProcessInfo() {}
+
+    virtual bool getPriority(int pid, int* priority) {
+        // For testing, use pid as priority.
+        // Lower the value higher the priority.
+        *priority = pid;
+        return true;
+    }
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo);
+};
+
+struct FakeDrm : public DrmSessionClientInterface {
+    FakeDrm() {}
+    virtual ~FakeDrm() {}
+
+    virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
+        mReclaimedSessions.push_back(sessionId);
+        return true;
+    }
+
+    const Vector<Vector<uint8_t> >& reclaimedSessions() const {
+        return mReclaimedSessions;
+    }
+
+private:
+    Vector<Vector<uint8_t> > mReclaimedSessions;
+
+    DISALLOW_EVIL_CONSTRUCTORS(FakeDrm);
+};
+
+static const int kTestPid1 = 30;
+static const int kTestPid2 = 20;
+static const uint8_t kTestSessionId1[] = {1, 2, 3};
+static const uint8_t kTestSessionId2[] = {4, 5, 6, 7, 8};
+static const uint8_t kTestSessionId3[] = {9, 0};
+
+class DrmSessionManagerTest : public ::testing::Test {
+public:
+    DrmSessionManagerTest()
+        : mDrmSessionManager(new DrmSessionManager(new FakeProcessInfo())),
+          mTestDrm1(new FakeDrm()),
+          mTestDrm2(new FakeDrm()) {
+        GetSessionId(kTestSessionId1, ARRAY_SIZE(kTestSessionId1), &mSessionId1);
+        GetSessionId(kTestSessionId2, ARRAY_SIZE(kTestSessionId2), &mSessionId2);
+        GetSessionId(kTestSessionId3, ARRAY_SIZE(kTestSessionId3), &mSessionId3);
+    }
+
+protected:
+    static void GetSessionId(const uint8_t* ids, size_t num, Vector<uint8_t>* sessionId) {
+        for (size_t i = 0; i < num; ++i) {
+            sessionId->push_back(ids[i]);
+        }
+    }
+
+    static void ExpectEqSessionInfo(const SessionInfo& info, sp<DrmSessionClientInterface> drm,
+            const Vector<uint8_t>& sessionId, int64_t timeStamp) {
+        EXPECT_EQ(drm, info.drm);
+        EXPECT_TRUE(isEqualSessionId(sessionId, info.sessionId));
+        EXPECT_EQ(timeStamp, info.timeStamp);
+    }
+
+    void addSession() {
+        mDrmSessionManager->addSession(kTestPid1, mTestDrm1, mSessionId1);
+        mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId2);
+        mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId3);
+        const PidSessionInfosMap& map = sessionMap();
+        EXPECT_EQ(2u, map.size());
+        ssize_t index1 = map.indexOfKey(kTestPid1);
+        ASSERT_GE(index1, 0);
+        const SessionInfos& infos1 = map[index1];
+        EXPECT_EQ(1u, infos1.size());
+        ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 0);
+
+        ssize_t index2 = map.indexOfKey(kTestPid2);
+        ASSERT_GE(index2, 0);
+        const SessionInfos& infos2 = map[index2];
+        EXPECT_EQ(2u, infos2.size());
+        ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId2, 1);
+        ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 2);
+    }
+
+    const PidSessionInfosMap& sessionMap() {
+        return mDrmSessionManager->mSessionMap;
+    }
+
+    void testGetLowestPriority() {
+        int pid;
+        int priority;
+        EXPECT_FALSE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
+
+        addSession();
+        EXPECT_TRUE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
+
+        EXPECT_EQ(kTestPid1, pid);
+        FakeProcessInfo processInfo;
+        int priority1;
+        processInfo.getPriority(kTestPid1, &priority1);
+        EXPECT_EQ(priority1, priority);
+    }
+
+    void testGetLeastUsedSession() {
+        sp<DrmSessionClientInterface> drm;
+        Vector<uint8_t> sessionId;
+        EXPECT_FALSE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
+
+        addSession();
+
+        EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
+        EXPECT_EQ(mTestDrm1, drm);
+        EXPECT_TRUE(isEqualSessionId(mSessionId1, sessionId));
+
+        EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
+        EXPECT_EQ(mTestDrm2, drm);
+        EXPECT_TRUE(isEqualSessionId(mSessionId2, sessionId));
+
+        // mSessionId2 is no longer the least used session.
+        mDrmSessionManager->useSession(mSessionId2);
+        EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
+        EXPECT_EQ(mTestDrm2, drm);
+        EXPECT_TRUE(isEqualSessionId(mSessionId3, sessionId));
+    }
+
+    sp<DrmSessionManager> mDrmSessionManager;
+    sp<FakeDrm> mTestDrm1;
+    sp<FakeDrm> mTestDrm2;
+    Vector<uint8_t> mSessionId1;
+    Vector<uint8_t> mSessionId2;
+    Vector<uint8_t> mSessionId3;
+};
+
+TEST_F(DrmSessionManagerTest, addSession) {
+    addSession();
+}
+
+TEST_F(DrmSessionManagerTest, useSession) {
+    addSession();
+
+    mDrmSessionManager->useSession(mSessionId1);
+    mDrmSessionManager->useSession(mSessionId3);
+
+    const PidSessionInfosMap& map = sessionMap();
+    const SessionInfos& infos1 = map.valueFor(kTestPid1);
+    const SessionInfos& infos2 = map.valueFor(kTestPid2);
+    ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 3);
+    ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 4);
+}
+
+TEST_F(DrmSessionManagerTest, removeSession) {
+    addSession();
+
+    mDrmSessionManager->removeSession(mSessionId2);
+
+    const PidSessionInfosMap& map = sessionMap();
+    EXPECT_EQ(2u, map.size());
+    const SessionInfos& infos1 = map.valueFor(kTestPid1);
+    const SessionInfos& infos2 = map.valueFor(kTestPid2);
+    EXPECT_EQ(1u, infos1.size());
+    EXPECT_EQ(1u, infos2.size());
+    // mSessionId2 has been removed.
+    ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId3, 2);
+}
+
+TEST_F(DrmSessionManagerTest, removeDrm) {
+    addSession();
+
+    sp<FakeDrm> drm = new FakeDrm;
+    const uint8_t ids[] = {123};
+    Vector<uint8_t> sessionId;
+    GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
+    mDrmSessionManager->addSession(kTestPid2, drm, sessionId);
+
+    mDrmSessionManager->removeDrm(mTestDrm2);
+
+    const PidSessionInfosMap& map = sessionMap();
+    const SessionInfos& infos2 = map.valueFor(kTestPid2);
+    EXPECT_EQ(1u, infos2.size());
+    // mTestDrm2 has been removed.
+    ExpectEqSessionInfo(infos2[0], drm, sessionId, 3);
+}
+
+TEST_F(DrmSessionManagerTest, reclaimSession) {
+    EXPECT_FALSE(mDrmSessionManager->reclaimSession(kTestPid1));
+    addSession();
+
+    // calling pid priority is too low
+    EXPECT_FALSE(mDrmSessionManager->reclaimSession(50));
+
+    EXPECT_TRUE(mDrmSessionManager->reclaimSession(10));
+    EXPECT_EQ(1u, mTestDrm1->reclaimedSessions().size());
+    EXPECT_TRUE(isEqualSessionId(mSessionId1, mTestDrm1->reclaimedSessions()[0]));
+
+    mDrmSessionManager->removeSession(mSessionId1);
+
+    // add a session from a higher priority process.
+    sp<FakeDrm> drm = new FakeDrm;
+    const uint8_t ids[] = {1, 3, 5};
+    Vector<uint8_t> sessionId;
+    GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
+    mDrmSessionManager->addSession(15, drm, sessionId);
+
+    EXPECT_TRUE(mDrmSessionManager->reclaimSession(18));
+    EXPECT_EQ(1u, mTestDrm2->reclaimedSessions().size());
+    // mSessionId2 is reclaimed.
+    EXPECT_TRUE(isEqualSessionId(mSessionId2, mTestDrm2->reclaimedSessions()[0]));
+}
+
+TEST_F(DrmSessionManagerTest, getLowestPriority) {
+    testGetLowestPriority();
+}
+
+TEST_F(DrmSessionManagerTest, getLeastUsedSession_l) {
+    testGetLeastUsedSession();
+}
+
+} // namespace android
