Merge "heif: cache the entire stream if possible to support seek" into oc-mr1-dev
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 51440d6..155362c 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -171,14 +171,13 @@
     setDeviceId(mAudioTrack->getRoutedDeviceId());
     mAudioTrack->addAudioDeviceCallback(mDeviceCallback);
 
-    // Update performance mode based on the actual stream.
+    // Update performance mode based on the actual stream flags.
     // For example, if the sample rate is not allowed then you won't get a FAST track.
     audio_output_flags_t actualFlags = mAudioTrack->getFlags();
     aaudio_performance_mode_t actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
-    if ((actualFlags & (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW))
-        == (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)) {
+    // We may not get the RAW flag. But as long as we get the FAST flag we can call it LOW_LATENCY.
+    if ((actualFlags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
         actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
-
     } else if ((actualFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
         actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING;
     }
diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp
index 1f188f3..2a74512 100644
--- a/media/libmedia/MediaCodecInfo.cpp
+++ b/media/libmedia/MediaCodecInfo.cpp
@@ -105,11 +105,17 @@
     ProfileLevel profileLevel;
     profileLevel.mProfile = profile;
     profileLevel.mLevel = level;
-    mProfileLevels.push_back(profileLevel);
+    if (mProfileLevelsSorted.indexOf(profileLevel) < 0) {
+        mProfileLevels.push_back(profileLevel);
+        mProfileLevelsSorted.add(profileLevel);
+    }
 }
 
 void MediaCodecInfo::CapabilitiesBuilder::addColorFormat(uint32_t format) {
-    mColorFormats.push(format);
+    if (mColorFormatsSorted.indexOf(format) < 0) {
+        mColorFormats.push(format);
+        mColorFormatsSorted.add(format);
+    }
 }
 
 void MediaCodecInfo::CapabilitiesBuilder::addFlags(uint32_t flags) {
diff --git a/media/libmedia/include/media/IOMX.h b/media/libmedia/include/media/IOMX.h
index d868860..e69c02d 100644
--- a/media/libmedia/include/media/IOMX.h
+++ b/media/libmedia/include/media/IOMX.h
@@ -31,6 +31,7 @@
 
 #include <media/openmax/OMX_Core.h>
 #include <media/openmax/OMX_Video.h>
+#include <media/openmax/OMX_VideoExt.h>
 
 namespace android {
 
diff --git a/media/libmedia/include/media/MediaCodecInfo.h b/media/libmedia/include/media/MediaCodecInfo.h
index 6b50f22..ef641d2 100644
--- a/media/libmedia/include/media/MediaCodecInfo.h
+++ b/media/libmedia/include/media/MediaCodecInfo.h
@@ -40,6 +40,9 @@
     struct ProfileLevel {
         uint32_t mProfile;
         uint32_t mLevel;
+        bool operator <(const ProfileLevel &o) const {
+            return mProfile < o.mProfile || (mProfile == o.mProfile && mLevel < o.mLevel);
+        }
     };
 
     struct Capabilities : public RefBase {
@@ -61,7 +64,9 @@
 
     protected:
         Vector<ProfileLevel> mProfileLevels;
+        SortedVector<ProfileLevel> mProfileLevelsSorted;
         Vector<uint32_t> mColorFormats;
+        SortedVector<uint32_t> mColorFormatsSorted;
         uint32_t mFlags;
         sp<AMessage> mDetails;
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 63ad0e0..0e60b2e 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -4173,11 +4173,12 @@
 // static
 int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
         int width, int height, int rate, int bitrate,
-        OMX_VIDEO_AVCPROFILETYPE profile) {
+        OMX_VIDEO_AVCPROFILEEXTTYPE profile) {
     // convert bitrate to main/baseline profile kbps equivalent
-    switch (profile) {
+    switch ((uint32_t)profile) {
         case OMX_VIDEO_AVCProfileHigh10:
             bitrate = divUp(bitrate, 3000); break;
+        case OMX_VIDEO_AVCProfileConstrainedHigh:
         case OMX_VIDEO_AVCProfileHigh:
             bitrate = divUp(bitrate, 1250); break;
         default:
@@ -8262,6 +8263,17 @@
             }
             builder->addProfileLevel(param.eProfile, param.eLevel);
 
+            // AVC components may not list the constrained profiles explicitly, but
+            // decoders that support a profile also support its constrained version.
+            // Encoders must explicitly support constrained profiles.
+            if (!isEncoder && mime.equalsIgnoreCase(MEDIA_MIMETYPE_VIDEO_AVC)) {
+                if (param.eProfile == OMX_VIDEO_AVCProfileHigh) {
+                    builder->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel);
+                } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) {
+                    builder->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel);
+                }
+            }
+
             if (index == kMaxIndicesToCheck) {
                 ALOGW("[%s] stopping checking profiles after %u: %x/%x",
                         name.c_str(), index,
@@ -8275,7 +8287,6 @@
         OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
         InitOMXParams(&portFormat);
         portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
-        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
             portFormat.nIndex = index;
             status_t err = omxNode->getParameter(
@@ -8289,19 +8300,8 @@
             if (IsFlexibleColorFormat(
                     omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
                     &flexibleEquivalent)) {
-                bool marked = false;
-                for (size_t i = 0; i < supportedColors.size(); ++i) {
-                    if (supportedColors[i] == flexibleEquivalent) {
-                        marked = true;
-                        break;
-                    }
-                }
-                if (!marked) {
-                    supportedColors.push(flexibleEquivalent);
-                    builder->addColorFormat(flexibleEquivalent);
-                }
+                builder->addColorFormat(flexibleEquivalent);
             }
-            supportedColors.push(portFormat.eColorFormat);
             builder->addColorFormat(portFormat.eColorFormat);
 
             if (index == kMaxIndicesToCheck) {
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index a3bda5d..3ef8f2a 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -237,6 +237,11 @@
     OMX_VIDEO_AVCPROFILETYPE codecProfile;
     OMX_VIDEO_AVCLEVELTYPE codecLevel;
     if (profiles.map(profile, &codecProfile)) {
+        if (profile == 66 && (constraints & 0x40)) {
+            codecProfile = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedBaseline;
+        } else if (profile == 100 && (constraints & 0x0C) == 0x0C) {
+            codecProfile = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedHigh;
+        }
         format->setInt32("profile", codecProfile);
         if (levels.map(level, &codecLevel)) {
             // for 9 && 11 decide level based on profile and constraint_set3 flag
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index 248ab6d..c342b6c 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -48,10 +48,14 @@
         (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
 
 static const CodecProfileLevel kProfileLevels[] = {
+    { OMX_VIDEO_AVCProfileConstrainedBaseline, OMX_VIDEO_AVCLevel52 },
+
     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel52 },
 
     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel52 },
 
+    { OMX_VIDEO_AVCProfileConstrainedHigh,     OMX_VIDEO_AVCLevel52 },
+
     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel52 },
 };
 
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 326207b..ce7efba 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -74,33 +74,11 @@
 };
 
 static const CodecProfileLevel kProfileLevels[] = {
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1  },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11 },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12 },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13 },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2  },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21 },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22 },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3  },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31 },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4  },
-    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1  },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11 },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12 },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13 },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2  },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21 },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22 },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3  },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31 },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32 },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4  },
-    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel41 },
+    { OMX_VIDEO_AVCProfileConstrainedBaseline, OMX_VIDEO_AVCLevel41 },
 
+    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
+
+    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel41 },
 };
 
 static size_t GetCPUCoreCount() {
@@ -962,7 +940,8 @@
                 return OMX_ErrorUndefined;
             }
 
-            avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline;
+            // TODO: maintain profile
+            avcParams->eProfile = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedBaseline;
             avcParams->eLevel = omxLevel;
             avcParams->nRefFrames = 1;
             avcParams->bUseHadamard = OMX_TRUE;
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index 411a251..39b67ab 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -31,20 +31,12 @@
 namespace android {
 
 static const CodecProfileLevel kM4VProfileLevels[] = {
-    { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0 },
-    { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b },
-    { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1 },
-    { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2 },
     { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3 },
 };
 
 static const CodecProfileLevel kH263ProfileLevels[] = {
-    { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10 },
-    { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20 },
     { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30 },
     { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45 },
-    { OMX_VIDEO_H263ProfileISWV2,    OMX_VIDEO_H263Level10 },
-    { OMX_VIDEO_H263ProfileISWV2,    OMX_VIDEO_H263Level20 },
     { OMX_VIDEO_H263ProfileISWV2,    OMX_VIDEO_H263Level30 },
     { OMX_VIDEO_H263ProfileISWV2,    OMX_VIDEO_H263Level45 },
 };
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index d049df5..b9f48c4 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -94,7 +94,8 @@
     // some OMX components as auto level, and by others as invalid level.
     static int /* OMX_VIDEO_AVCLEVELTYPE */ getAVCLevelFor(
             int width, int height, int rate, int bitrate,
-            OMX_VIDEO_AVCPROFILETYPE profile = OMX_VIDEO_AVCProfileBaseline);
+            OMX_VIDEO_AVCPROFILEEXTTYPE profile =
+                (OMX_VIDEO_AVCPROFILEEXTTYPE)OMX_VIDEO_AVCProfileBaseline);
 
     // Quirk still supported, even though deprecated
     enum Quirks {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 02f5424..94e8f3b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2439,25 +2439,6 @@
     nsecs_t sensorTimestamp = request.sensorTimestamp;
     nsecs_t shutterTimestamp = request.shutterTimestamp;
 
-    bool skipResultMetadata = false;
-    if (request.requestStatus != OK) {
-        switch (request.requestStatus) {
-            case CAMERA3_MSG_ERROR_DEVICE:
-            case CAMERA3_MSG_ERROR_REQUEST:
-            case CAMERA3_MSG_ERROR_RESULT:
-                skipResultMetadata = true;
-                break;
-            case CAMERA3_MSG_ERROR_BUFFER:
-                //Result metadata should return in this case.
-                skipResultMetadata = false;
-                break;
-            default:
-                SET_ERR("Unknown error message: %d", request.requestStatus);
-                skipResultMetadata = false;
-                break;
-        }
-    }
-
     // Check if it's okay to remove the request from InFlightMap:
     // In the case of a successful request:
     //      all input and output buffers, all result metadata, shutter callback
@@ -2465,7 +2446,7 @@
     // In the case of a unsuccessful request:
     //      all input and output buffers arrived.
     if (request.numBuffersLeft == 0 &&
-            (skipResultMetadata ||
+            (request.skipResultMetadata ||
             (request.haveResultMetadata && shutterTimestamp != 0))) {
         ATRACE_ASYNC_END("frame capture", frameNumber);
 
@@ -2941,6 +2922,11 @@
                     InFlightRequest &r = mInFlightMap.editValueAt(idx);
                     r.requestStatus = msg.error_code;
                     resultExtras = r.resultExtras;
+                    if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT == errorCode
+                            ||  hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST ==
+                            errorCode) {
+                        r.skipResultMetadata = true;
+                    }
                     if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT ==
                             errorCode) {
                         // In case of missing result check whether the buffers
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index b5f19d7..363bd88 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -885,6 +885,11 @@
         // For auto-exposure modes, equal to 1/(lower end of target FPS range)
         nsecs_t maxExpectedDuration;
 
+        // Whether the result metadata for this request is to be skipped. The
+        // result metadata should be skipped in the case of
+        // REQUEST/RESULT error.
+        bool skipResultMetadata;
+
         // Default constructor needed by KeyedVector
         InFlightRequest() :
                 shutterTimestamp(0),
@@ -894,7 +899,8 @@
                 numBuffersLeft(0),
                 hasInputBuffer(false),
                 hasCallback(true),
-                maxExpectedDuration(kDefaultExpectedDuration) {
+                maxExpectedDuration(kDefaultExpectedDuration),
+                skipResultMetadata(false) {
         }
 
         InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
@@ -907,7 +913,8 @@
                 resultExtras(extras),
                 hasInputBuffer(hasInput),
                 hasCallback(hasAppCallback),
-                maxExpectedDuration(maxDuration) {
+                maxExpectedDuration(maxDuration),
+                skipResultMetadata(false) {
         }
     };