Merge "Camera1: Don't send partial results to ZSL clients"
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 8ec7f1c..84b6bab 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -278,6 +278,7 @@
     status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg);
     status_t setupH263EncoderParameters(const sp<AMessage> &msg);
     status_t setupAVCEncoderParameters(const sp<AMessage> &msg);
+    status_t setupHEVCEncoderParameters(const sp<AMessage> &msg);
     status_t setupVPXEncoderParameters(const sp<AMessage> &msg);
 
     status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 9ab1417..2a583d0 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -2035,6 +2035,10 @@
             err = setupAVCEncoderParameters(msg);
             break;
 
+        case OMX_VIDEO_CodingHEVC:
+            err = setupHEVCEncoderParameters(msg);
+            break;
+
         case OMX_VIDEO_CodingVP8:
         case OMX_VIDEO_CodingVP9:
             err = setupVPXEncoderParameters(msg);
@@ -2371,6 +2375,62 @@
     return configureBitrate(bitrate, bitrateMode);
 }
 
+status_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
+    int32_t bitrate, iFrameInterval;
+    if (!msg->findInt32("bitrate", &bitrate)
+            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
+        return INVALID_OPERATION;
+    }
+
+    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
+
+    float frameRate;
+    if (!msg->findFloat("frame-rate", &frameRate)) {
+        int32_t tmp;
+        if (!msg->findInt32("frame-rate", &tmp)) {
+            return INVALID_OPERATION;
+        }
+        frameRate = (float)tmp;
+    }
+
+    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
+    InitOMXParams(&hevcType);
+    hevcType.nPortIndex = kPortIndexOutput;
+
+    status_t err = OK;
+    err = mOMX->getParameter(
+            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
+    if (err != OK) {
+        return err;
+    }
+
+    int32_t profile;
+    if (msg->findInt32("profile", &profile)) {
+        int32_t level;
+        if (!msg->findInt32("level", &level)) {
+            return INVALID_OPERATION;
+        }
+
+        err = verifySupportForProfileAndLevel(profile, level);
+        if (err != OK) {
+            return err;
+        }
+
+        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
+        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
+    }
+
+    // TODO: Need OMX structure definition for setting iFrameInterval
+
+    err = mOMX->setParameter(
+            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
+    if (err != OK) {
+        return err;
+    }
+
+    return configureBitrate(bitrate, bitrateMode);
+}
+
 status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
     int32_t bitrate;
     int32_t iFrameInterval = 0;
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 64bf2b6..ab30865 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -65,10 +65,9 @@
       mInputBufferCount(0),
       mOutputBufferCount(0),
       mSignalledError(false),
+      mLastInHeader(NULL),
+      mCurrentInputTime(0),
       mOutputPortSettingsChange(NONE) {
-    for (unsigned int i = 0; i < kNumDelayBlocksMax; i++) {
-        mAnchorTimeUs[i] = 0;
-    }
     initPorts();
     CHECK_EQ(initDecoder(), (status_t)OK);
 }
@@ -496,14 +495,11 @@
             } else {
                 mEndOfInput = false;
             }
-            if (inHeader->nOffset == 0) { // TODO: does nOffset != 0 happen?
-                mAnchorTimeUs[mInputBufferCount % kNumDelayBlocksMax] =
-                        inHeader->nTimeStamp;
-            }
 
             if (inHeader->nFilledLen == 0) {
                 inInfo->mOwnedByUs = false;
                 inQueue.erase(inQueue.begin());
+                mLastInHeader = NULL;
                 inInfo = NULL;
                 notifyEmptyBufferDone(inHeader);
                 inHeader = NULL;
@@ -568,6 +564,18 @@
                 INT prevSampleRate = mStreamInfo->sampleRate;
                 INT prevNumChannels = mStreamInfo->numChannels;
 
+                if (inHeader != mLastInHeader) {
+                    mLastInHeader = inHeader;
+                    mCurrentInputTime = inHeader->nTimeStamp;
+                } else {
+                    if (mStreamInfo->sampleRate) {
+                        mCurrentInputTime += mStreamInfo->aacSamplesPerFrame *
+                                1000000ll / mStreamInfo->sampleRate;
+                    } else {
+                        ALOGW("no sample rate yet");
+                    }
+                }
+                mAnchorTimes.add(mCurrentInputTime);
                 aacDecoder_Fill(mAACDecoder,
                                 inBuffer,
                                 inBufferLength,
@@ -671,6 +679,7 @@
                             inInfo->mOwnedByUs = false;
                             mInputBufferCount++;
                             inQueue.erase(inQueue.begin());
+                            mLastInHeader = NULL;
                             inInfo = NULL;
                             notifyEmptyBufferDone(inHeader);
                             inHeader = NULL;
@@ -687,11 +696,12 @@
                     inInfo->mOwnedByUs = false;
                     mInputBufferCount++;
                     inQueue.erase(inQueue.begin());
+                    mLastInHeader = NULL;
                     inInfo = NULL;
                     notifyEmptyBufferDone(inHeader);
                     inHeader = NULL;
                 } else {
-                    ALOGW("inHeader->nFilledLen = %d", inHeader->nFilledLen);
+                    ALOGV("inHeader->nFilledLen = %d", inHeader->nFilledLen);
                 }
             }
         }
@@ -779,8 +789,8 @@
                 outHeader->nFlags = 0;
             }
 
-            outHeader->nTimeStamp = mAnchorTimeUs[mOutputBufferCount
-                    % kNumDelayBlocksMax];
+            outHeader->nTimeStamp = mAnchorTimes.isEmpty() ? 0 : mAnchorTimes.itemAt(0);
+            mAnchorTimes.removeAt(0);
 
             mOutputBufferCount++;
             outInfo->mOwnedByUs = false;
@@ -820,8 +830,8 @@
                     outHeader->nFilledLen = 0;
                     outHeader->nFlags = OMX_BUFFERFLAG_EOS;
 
-                    outHeader->nTimeStamp = mAnchorTimeUs[mOutputBufferCount
-                            % kNumDelayBlocksMax];
+                    outHeader->nTimeStamp = mAnchorTimes.itemAt(0);
+                    mAnchorTimes.removeAt(0);
 
                     mOutputBufferCount++;
                     outInfo->mOwnedByUs = false;
@@ -842,6 +852,8 @@
         // depend on fragments from the last one decoded.
         // drain all existing data
         drainDecoder();
+        mAnchorTimes.clear();
+        mLastInHeader = NULL;
     } else {
         while (outputDelayRingBufferSamplesAvailable() > 0) {
             int32_t ns = outputDelayRingBufferGetSamples(0,
@@ -896,6 +908,8 @@
     mOutputDelayRingBufferReadPos = 0;
     mEndOfInput = false;
     mEndOfOutput = false;
+    mAnchorTimes.clear();
+    mLastInHeader = NULL;
 
     // To make the codec behave the same before and after a reset, we need to invalidate the
     // streaminfo struct. This does that:
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 5cde03a..865bd15 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -58,7 +58,9 @@
     size_t mInputBufferCount;
     size_t mOutputBufferCount;
     bool mSignalledError;
-    int64_t mAnchorTimeUs[kNumDelayBlocksMax];
+    OMX_BUFFERHEADERTYPE *mLastInHeader;
+    int64_t mCurrentInputTime;
+    Vector<int64_t> mAnchorTimes;
 
     CDrcPresModeWrapper mDrcWrap;
 
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index ee02516..4fcf43b 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -4218,9 +4218,7 @@
     if (stream == AUDIO_STREAM_MUSIC &&
         index != mStreams[stream].mIndexMin &&
         (device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
-         device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET ||
-         device == AUDIO_DEVICE_OUT_USB_ACCESSORY ||
-         device == AUDIO_DEVICE_OUT_USB_DEVICE)) {
+         device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) {
         return 1.0;
     }