Merge "Add HEVC encoder support to ACodec"
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;