diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 8a962c6..ac9bf91 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -260,6 +260,7 @@
     srcs: [
         "AudioCapabilities.cpp",
         "CodecCapabilities.cpp",
+        "VideoCapabilities.cpp",
         "CodecCapabilitiesUtils.cpp",
     ],
 
diff --git a/media/libmedia/CodecCapabilitiesUtils.cpp b/media/libmedia/CodecCapabilitiesUtils.cpp
index ef28fcb..01bb24e 100644
--- a/media/libmedia/CodecCapabilitiesUtils.cpp
+++ b/media/libmedia/CodecCapabilitiesUtils.cpp
@@ -16,19 +16,146 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "CodecCapabilitiesUtils"
+
+#include <android-base/properties.h>
 #include <utils/Log.h>
 
 #include <algorithm>
 #include <cmath>
-#include <regex>
+#include <cstdlib>
 #include <string>
 #include <vector>
 
 #include <media/CodecCapabilitiesUtils.h>
-
+#include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AUtils.h>
 
 namespace android {
 
+// VideoSize
+
+VideoSize::VideoSize(int32_t width, int32_t height) : mWidth(width), mHeight(height) {}
+
+VideoSize::VideoSize() : mWidth(0), mHeight(0) {}
+
+int32_t VideoSize::getWidth() const { return mWidth; }
+
+int32_t VideoSize::getHeight() const { return mHeight; }
+
+bool VideoSize::equals(VideoSize other) const {
+    return mWidth == other.mWidth && mHeight == other.mHeight;
+}
+
+bool VideoSize::empty() const {
+    return mWidth <= 0 || mHeight <= 0;
+}
+
+std::string VideoSize::toString() const {
+    return std::to_string(mWidth) + "x" + std::to_string(mHeight);
+}
+
+std::optional<VideoSize> VideoSize::ParseSize(std::string str) {
+    if (str.empty()) {
+        return std::nullopt;
+    }
+
+    std::regex regex("([0-9]+)([*x])([0-9]+)");
+    std::smatch match;
+    if (std::regex_match(str, match, regex)) {
+        long int w = strtol(match[1].str().c_str(), NULL, 10);
+        long int h = strtol(match[3].str().c_str(), NULL, 10);
+        return std::make_optional(VideoSize(w, h));
+    } else {
+        ALOGW("could not parse size %s", str.c_str());
+        return std::nullopt;
+    }
+}
+
+std::optional<std::pair<VideoSize, VideoSize>> VideoSize::ParseSizeRange(const std::string str) {
+    size_t ix = str.find_first_of('-');
+    if (ix != std::string::npos) {
+        std::optional<VideoSize> lowerOpt = VideoSize::ParseSize(str.substr(0, ix));
+        std::optional<VideoSize> upperOpt = VideoSize::ParseSize(str.substr(ix + 1));
+        if (!lowerOpt || !upperOpt) {
+            return std::nullopt;
+        }
+        return std::make_optional(
+                std::pair<VideoSize, VideoSize>(lowerOpt.value(), upperOpt.value()));
+    } else {
+        std::optional<VideoSize> opt = VideoSize::ParseSize(str);
+        if (!opt) {
+            return std::nullopt;
+        }
+        return std::make_optional(std::pair<VideoSize, VideoSize>(opt.value(), opt.value()));
+    }
+}
+
+Range<int32_t> VideoSize::GetAllowedDimensionRange() {
+#ifdef __LP64__
+    return Range<int32_t>(1, 32768);
+#else
+    int32_t value = base::GetIntProperty("media.resolution.limit.32bit", (int32_t)4096);
+    return Range<int32_t>(1, value);
+#endif
+}
+
+// Rational
+
+std::optional<Rational> Rational::Parse(std::string str) {
+    if (str.compare("NaN") == 0) {
+        return std::make_optional(NaN);
+    } else if (str.compare("Infinity") == 0) {
+        return std::make_optional(POSITIVE_INFINITY);
+    } else if (str.compare("-Infinity") == 0) {
+        return std::make_optional(NEGATIVE_INFINITY);
+    }
+
+    std::regex regex("([0-9]+)([:/])([0-9]+)");
+    std::smatch match;
+    if (std::regex_match(str, match, regex)) {
+        long int numerator = strtol(match[1].str().c_str(), NULL, 10);
+        long int denominator = strtol(match[3].str().c_str(), NULL, 10);
+        return std::make_optional(Rational(numerator, denominator));
+    } else {
+        ALOGW("could not parse string: %s to Rational", str.c_str());
+        return std::nullopt;
+    }
+}
+
+Rational Rational::scale(int32_t num, int32_t den) {
+    int32_t common = std::gcd(num, den);
+    num /= common;
+    den /= common;
+    return Rational(
+            (int32_t)(mNumerator * (double)num),     // saturate to int
+            (int32_t)(mDenominator * (double)den));  // saturate to int
+}
+
+Range<Rational> Rational::ScaleRange(Range<Rational> range, int32_t num, int32_t den) {
+    if (num == den) {
+        return range;
+    }
+    return Range(
+            range.lower().scale(num, den),
+            range.upper().scale(num, den));
+}
+
+std::optional<Range<Rational>> Rational::ParseRange(const std::string str) {
+    size_t ix = str.find_first_of('-');
+    if (ix != std::string::npos) {
+        std::optional<Rational> lower = Parse(str.substr(0, ix));
+        std::optional<Rational> upper = Parse(str.substr(ix + 1));
+        if (!lower || !upper) {
+            return std::nullopt;
+        }
+        return std::make_optional<Range<Rational>>(lower.value(), upper.value());
+    } else {
+        std::optional<Rational> value = Parse(str);
+        if (!value) {
+            return std::nullopt;
+        }
+        return std::make_optional<Range<Rational>>(value.value(), value.value());
+    }
+}
 
 }  // namespace android
\ No newline at end of file
diff --git a/media/libmedia/VideoCapabilities.cpp b/media/libmedia/VideoCapabilities.cpp
new file mode 100644
index 0000000..bd26b8c
--- /dev/null
+++ b/media/libmedia/VideoCapabilities.cpp
@@ -0,0 +1,1702 @@
+/*
+ * Copyright 2024, 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 "VideoCapabilities"
+
+#include <android-base/strings.h>
+
+#include <media/CodecCapabilities.h>
+#include <media/VideoCapabilities.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaCodecConstants.h>
+
+#include <utils/Errors.h>
+
+namespace android {
+
+static const Range<int64_t> POSITIVE_INT64 = Range((int64_t)1, INT64_MAX);
+static const Range<int32_t> BITRATE_RANGE = Range<int32_t>(0, 500000000);
+static const Range<int32_t> FRAME_RATE_RANGE = Range<int32_t>(0, 960);
+static const Range<Rational> POSITIVE_RATIONALS =
+            Range<Rational>(Rational((int32_t)1, INT32_MAX), Rational(INT32_MAX, (int32_t)1));
+
+const Range<int32_t>& VideoCapabilities::getBitrateRange() const {
+    return mBitrateRange;
+}
+
+const Range<int32_t>& VideoCapabilities::getSupportedWidths() const {
+    return mWidthRange;
+}
+
+const Range<int32_t>& VideoCapabilities::getSupportedHeights() const {
+    return mHeightRange;
+}
+
+int32_t VideoCapabilities::getWidthAlignment() const {
+    return mWidthAlignment;
+}
+
+int32_t VideoCapabilities::getHeightAlignment() const {
+    return mHeightAlignment;
+}
+
+int32_t VideoCapabilities::getSmallerDimensionUpperLimit() const {
+    return mSmallerDimensionUpperLimit;
+}
+
+const Range<int32_t>& VideoCapabilities::getSupportedFrameRates() const {
+    return mFrameRateRange;
+}
+
+std::optional<Range<int32_t>> VideoCapabilities::getSupportedWidthsFor(int32_t height) const {
+    Range<int32_t> range = mWidthRange;
+    if (!mHeightRange.contains(height)
+            || (height % mHeightAlignment) != 0) {
+        ALOGE("unsupported height");
+        return std::nullopt;
+    }
+    const int32_t heightInBlocks = divUp(height, mBlockHeight);
+
+    // constrain by block count and by block aspect ratio
+    const int32_t minWidthInBlocks = std::max(
+            divUp(mBlockCountRange.lower(), heightInBlocks),
+            (int32_t)std::ceil(mBlockAspectRatioRange.lower().asDouble()
+                    * heightInBlocks));
+    const int32_t maxWidthInBlocks = std::min(
+            mBlockCountRange.upper() / heightInBlocks,
+            (int32_t)(mBlockAspectRatioRange.upper().asDouble()
+                    * heightInBlocks));
+    range = range.intersect(
+            (minWidthInBlocks - 1) * mBlockWidth + mWidthAlignment,
+            maxWidthInBlocks * mBlockWidth);
+
+    // constrain by smaller dimension limit
+    if (height > mSmallerDimensionUpperLimit) {
+        range = range.intersect(1, mSmallerDimensionUpperLimit);
+    }
+
+    // constrain by aspect ratio
+    range = range.intersect(
+            (int32_t)std::ceil(mAspectRatioRange.lower().asDouble()
+                    * height),
+            (int32_t)(mAspectRatioRange.upper().asDouble() * height));
+    return range;
+}
+
+std::optional<Range<int32_t>> VideoCapabilities::getSupportedHeightsFor(int32_t width) const {
+    Range<int32_t> range = mHeightRange;
+    if (!mWidthRange.contains(width)
+            || (width % mWidthAlignment) != 0) {
+        ALOGE("unsupported width");
+        return std::nullopt;
+    }
+    const int32_t widthInBlocks = divUp(width, mBlockWidth);
+
+    // constrain by block count and by block aspect ratio
+    const int32_t minHeightInBlocks = std::max(
+            divUp(mBlockCountRange.lower(), widthInBlocks),
+            (int32_t)std::ceil(widthInBlocks /
+                    mBlockAspectRatioRange.upper().asDouble()));
+    const int32_t maxHeightInBlocks = std::min(
+            mBlockCountRange.upper() / widthInBlocks,
+            (int32_t)(widthInBlocks /
+                    mBlockAspectRatioRange.lower().asDouble()));
+    range = range.intersect(
+            (minHeightInBlocks - 1) * mBlockHeight + mHeightAlignment,
+            maxHeightInBlocks * mBlockHeight);
+
+    // constrain by smaller dimension limit
+    if (width > mSmallerDimensionUpperLimit) {
+        range = range.intersect(1, mSmallerDimensionUpperLimit);
+    }
+
+    // constrain by aspect ratio
+    range = range.intersect(
+            (int32_t)std::ceil(width /
+                    mAspectRatioRange.upper().asDouble()),
+            (int32_t)(width / mAspectRatioRange.lower().asDouble()));
+    return range;
+}
+
+std::optional<Range<double>> VideoCapabilities::getSupportedFrameRatesFor(
+        int32_t width, int32_t height) const {
+    if (!supports(std::make_optional<int32_t>(width), std::make_optional<int32_t>(height),
+            std::nullopt /* rate */)) {
+        ALOGE("Unsupported size. width: %d, height: %d", width, height);
+        return std::nullopt;
+    }
+
+    const int32_t blockCount =
+            divUp(width, mBlockWidth) * divUp(height, mBlockHeight);
+
+    return std::make_optional(Range(
+            std::max(mBlocksPerSecondRange.lower() / (double) blockCount,
+                (double) mFrameRateRange.lower()),
+            std::min(mBlocksPerSecondRange.upper() / (double) blockCount,
+                (double) mFrameRateRange.upper())));
+}
+
+int32_t VideoCapabilities::getBlockCount(int32_t width, int32_t height) const {
+    return divUp(width, mBlockWidth) * divUp(height, mBlockHeight);
+}
+
+std::optional<VideoSize> VideoCapabilities::findClosestSize(
+        int32_t width, int32_t height) const {
+    int32_t targetBlockCount = getBlockCount(width, height);
+    std::optional<VideoSize> closestSize;
+    int32_t minDiff = INT32_MAX;
+    for (const auto &[size, range] : mMeasuredFrameRates) {
+        int32_t diff = std::abs(targetBlockCount -
+                getBlockCount(size.getWidth(), size.getHeight()));
+        if (diff < minDiff) {
+            minDiff = diff;
+            closestSize = size;
+        }
+    }
+    return closestSize;
+}
+
+std::optional<Range<double>> VideoCapabilities::estimateFrameRatesFor(
+        int32_t width, int32_t height) const {
+    std::optional<VideoSize> size = findClosestSize(width, height);
+    if (!size) {
+        return std::nullopt;
+    }
+    auto rangeItr = mMeasuredFrameRates.find(size.value());
+    if (rangeItr == mMeasuredFrameRates.end()) {
+        return std::nullopt;
+    }
+    Range<int64_t> range = rangeItr->second;
+    double ratio = getBlockCount(size.value().getWidth(), size.value().getHeight())
+            / (double)std::max(getBlockCount(width, height), 1);
+    return std::make_optional(Range(range.lower() * ratio, range.upper() * ratio));
+}
+
+std::optional<Range<double>> VideoCapabilities::getAchievableFrameRatesFor(
+        int32_t width, int32_t height) const {
+    if (!supports(std::make_optional<int32_t>(width), std::make_optional<int32_t>(height),
+            std::nullopt /* rate */)) {
+        ALOGE("Unsupported size. width: %d, height: %d", width, height);
+        return std::nullopt;
+    }
+
+    if (mMeasuredFrameRates.empty()) {
+        ALOGW("Codec did not publish any measurement data.");
+        return std::nullopt;
+    }
+
+    return estimateFrameRatesFor(width, height);
+}
+
+// VideoCapabilities::PerformancePoint
+
+int32_t VideoCapabilities::PerformancePoint::getMaxMacroBlocks() const {
+    return saturateInt64ToInt32(mWidth * (int64_t)mHeight);
+}
+
+int32_t VideoCapabilities::PerformancePoint::getWidth() const {
+    return mWidth;
+}
+
+int32_t VideoCapabilities::PerformancePoint::getHeight() const {
+    return mHeight;
+}
+
+int32_t VideoCapabilities::PerformancePoint::getMaxFrameRate() const {
+    return mMaxFrameRate;
+}
+
+int64_t VideoCapabilities::PerformancePoint::getMaxMacroBlockRate() const {
+    return mMaxMacroBlockRate;
+}
+
+VideoSize VideoCapabilities::PerformancePoint::getBlockSize() const {
+    return mBlockSize;
+}
+
+std::string VideoCapabilities::PerformancePoint::toString() const {
+    int64_t blockWidth = 16 * (int64_t)mBlockSize.getWidth();
+    int64_t blockHeight = 16 * (int64_t)mBlockSize.getHeight();
+    int32_t origRate = (int32_t)divUp(mMaxMacroBlockRate, (int64_t)getMaxMacroBlocks());
+    std::string info = std::to_string(mWidth * (int64_t)16) + "x"
+            + std::to_string(mHeight * (int64_t)16) + "@" + std::to_string(origRate);
+    if (origRate < mMaxFrameRate) {
+        info += ", max " + std::to_string(mMaxFrameRate) + "fps";
+    }
+    if (blockWidth > 16 || blockHeight > 16) {
+        info += ", " + std::to_string(blockWidth) + "x"
+                + std::to_string(blockHeight) + " blocks";
+    }
+    return "PerformancePoint(" + info + ")";
+}
+
+void VideoCapabilities::PerformancePoint::init(int32_t width, int32_t height,
+        int32_t frameRate, int32_t maxFrameRate, VideoSize blockSize) {
+    mBlockSize = VideoSize(divUp(blockSize.getWidth(), (int32_t)16),
+                            divUp(blockSize.getHeight(), (int32_t)16));
+    // Use  IsPowerOfTwoStrict as we do not want width and height to be 0;
+    if (!IsPowerOfTwoStrict(blockSize.getWidth()) || !IsPowerOfTwoStrict(blockSize.getHeight())) {
+        ALOGE("The width and height of a PerformancePoint must be the power of two and not zero."
+                " width: %d, height: %d", blockSize.getWidth(), blockSize.getHeight());
+    }
+
+    // these are guaranteed not to overflow as we decimate by 16
+    mWidth = (int32_t)(divUp(std::max(width, 1),
+                            std::max(blockSize.getWidth(), 16))
+                        * mBlockSize.getWidth());
+    mHeight = (int32_t)(divUp(std::max(height, 1),
+                            std::max(blockSize.getHeight(), 16))
+                        * mBlockSize.getHeight());
+    mMaxFrameRate = std::max(std::max(frameRate, maxFrameRate), 1);
+    mMaxMacroBlockRate = std::max(frameRate, 1) * (int64_t)getMaxMacroBlocks();
+}
+
+VideoCapabilities::PerformancePoint::PerformancePoint(int32_t width, int32_t height,
+        int32_t frameRate, int32_t maxFrameRate, VideoSize blockSize) {
+    init(width, height, frameRate, maxFrameRate, blockSize);
+}
+
+VideoCapabilities::PerformancePoint::PerformancePoint(VideoSize blockSize, int32_t width,
+        int32_t height, int32_t maxFrameRate, int64_t maxMacroBlockRate) :
+        mBlockSize(blockSize), mWidth(width), mHeight(height), mMaxFrameRate(maxFrameRate),
+        mMaxMacroBlockRate(maxMacroBlockRate) {}
+
+VideoCapabilities::PerformancePoint::PerformancePoint(
+        const PerformancePoint &pp, VideoSize newBlockSize) {
+    init(16 * pp.mWidth, 16 * pp.mHeight,
+            // guaranteed not to overflow as these were multiplied at construction
+            (int32_t)divUp(pp.mMaxMacroBlockRate, (int64_t)pp.getMaxMacroBlocks()),
+            pp.mMaxFrameRate,
+            VideoSize(std::max(newBlockSize.getWidth(), 16 * pp.mBlockSize.getWidth()),
+                 std::max(newBlockSize.getHeight(), 16 * pp.mBlockSize.getHeight())));
+}
+
+VideoCapabilities::PerformancePoint::PerformancePoint(
+        int32_t width, int32_t height, int32_t frameRate) {
+    init(width, height, frameRate, frameRate /* maxFrameRate */, VideoSize(16, 16));
+}
+
+int32_t VideoCapabilities::PerformancePoint::saturateInt64ToInt32(int64_t value) const {
+    if (value < INT32_MIN) {
+        return INT32_MIN;
+    } else if (value > INT32_MAX) {
+        return INT32_MAX;
+    } else {
+        return (int32_t)value;
+    }
+}
+
+/* This method may overflow */
+int32_t VideoCapabilities::PerformancePoint::align(
+        int32_t value, int32_t alignment) const {
+    return divUp(value, alignment) * alignment;
+}
+
+bool VideoCapabilities::PerformancePoint::covers(
+        const sp<AMessage> &format) const {
+    int32_t width, height;
+    format->findInt32(KEY_WIDTH, &width);
+    format->findInt32(KEY_HEIGHT, &height);
+    double frameRate;
+    format->findDouble(KEY_FRAME_RATE, &frameRate);
+    PerformancePoint other = PerformancePoint(
+            width, height,
+            // safely convert ceil(double) to int through float cast and std::round
+            std::round((float)(std::ceil(frameRate)))
+    );
+    return covers(other);
+}
+
+bool VideoCapabilities::PerformancePoint::covers(
+        const PerformancePoint &other) const {
+    // convert performance points to common block size
+    VideoSize commonSize = getCommonBlockSize(other);
+    PerformancePoint aligned = PerformancePoint(*this, commonSize);
+    PerformancePoint otherAligned = PerformancePoint(other, commonSize);
+
+    return (aligned.getMaxMacroBlocks() >= otherAligned.getMaxMacroBlocks()
+            && aligned.mMaxFrameRate >= otherAligned.mMaxFrameRate
+            && aligned.mMaxMacroBlockRate >= otherAligned.mMaxMacroBlockRate);
+}
+
+VideoSize VideoCapabilities::PerformancePoint::getCommonBlockSize(
+        const PerformancePoint &other) const {
+    return VideoSize(
+            16 * std::max(mBlockSize.getWidth(), other.mBlockSize.getWidth()),
+            16 * std::max(mBlockSize.getHeight(), other.mBlockSize.getHeight()));
+}
+
+bool VideoCapabilities::PerformancePoint::equals(
+        const PerformancePoint &other) const {
+    // convert performance points to common block size
+    VideoSize commonSize = getCommonBlockSize(other);
+    PerformancePoint aligned = PerformancePoint(*this, commonSize);
+    PerformancePoint otherAligned = PerformancePoint(other, commonSize);
+
+    return (aligned.getMaxMacroBlocks() == otherAligned.getMaxMacroBlocks()
+            && aligned.mMaxFrameRate == otherAligned.mMaxFrameRate
+            && aligned.mMaxMacroBlockRate == otherAligned.mMaxMacroBlockRate);
+}
+
+// VideoCapabilities
+
+const std::vector<VideoCapabilities::PerformancePoint>&
+        VideoCapabilities::getSupportedPerformancePoints() const {
+    return mPerformancePoints;
+}
+
+bool VideoCapabilities::areSizeAndRateSupported(
+        int32_t width, int32_t height, double frameRate) const {
+    return supports(std::make_optional<int32_t>(width), std::make_optional<int32_t>(height),
+            std::make_optional<double>(frameRate));
+}
+
+bool VideoCapabilities::isSizeSupported(int32_t width, int32_t height) const {
+    return supports(std::make_optional<int32_t>(width), std::make_optional<int32_t>(height),
+            std::nullopt /* rate */);
+}
+
+bool VideoCapabilities::supports(std::optional<int32_t> width, std::optional<int32_t> height,
+        std::optional<double> rate) const {
+    bool ok = true;
+
+    if (width) {
+        ok &= mWidthRange.contains(width.value())
+                && (width.value() % mWidthAlignment == 0);
+    }
+    if (height) {
+        ok &= mHeightRange.contains(height.value())
+                && (height.value() % mHeightAlignment == 0);
+    }
+    if (rate) {
+        ok &= mFrameRateRange.contains(Range<int32_t>::RangeFor(rate.value()));
+    }
+    if (height && width) {
+        ok &= std::min(height.value(), width.value()) <= mSmallerDimensionUpperLimit;
+
+        const int32_t widthInBlocks = divUp(width.value(), mBlockWidth);
+        const int32_t heightInBlocks = divUp(height.value(), mBlockHeight);
+        const int32_t blockCount = widthInBlocks * heightInBlocks;
+        ok &= mBlockCountRange.contains(blockCount)
+                && mBlockAspectRatioRange.contains(
+                        Rational(widthInBlocks, heightInBlocks))
+                && mAspectRatioRange.contains(Rational(width.value(), height.value()));
+        if (rate) {
+            double blocksPerSec = blockCount * rate.value();
+            ok &= mBlocksPerSecondRange.contains(
+                    Range<int64_t>::RangeFor(blocksPerSec));
+        }
+    }
+    return ok;
+}
+
+bool VideoCapabilities::supportsFormat(const sp<AMessage> &format) const {
+    int32_t widthVal, heightVal;
+    std::optional<int32_t> width = format->findInt32(KEY_WIDTH, &widthVal)
+            ? std::make_optional<int32_t>(widthVal) : std::nullopt;
+    std::optional<int32_t> height = format->findInt32(KEY_HEIGHT, &heightVal)
+            ? std::make_optional<int32_t>(heightVal) : std::nullopt;
+    double rateVal;
+    std::optional<double> rate = format->findDouble(KEY_FRAME_RATE, &rateVal)
+            ? std::make_optional<double>(rateVal) : std::nullopt;
+
+    if (!supports(width, height, rate)) {
+        return false;
+    }
+
+    if (!CodecCapabilities::SupportsBitrate(mBitrateRange, format)) {
+        return false;
+    }
+
+    // we ignore color-format for now as it is not reliably reported by codec
+    return true;
+}
+
+// static
+std::shared_ptr<VideoCapabilities> VideoCapabilities::Create(std::string mediaType,
+        std::vector<ProfileLevel> profLevs, const sp<AMessage> &format) {
+    std::shared_ptr<VideoCapabilities> caps(new VideoCapabilities());
+    caps->init(mediaType, profLevs, format);
+    return caps;
+}
+
+void VideoCapabilities::init(std::string mediaType, std::vector<ProfileLevel> profLevs,
+        const sp<AMessage> &format) {
+    mMediaType = mediaType;
+    mProfileLevels = profLevs;
+    mError = 0;
+
+    initWithPlatformLimits();
+    applyLevelLimits();
+    parseFromInfo(format);
+    updateLimits();
+}
+
+VideoSize VideoCapabilities::getBlockSize() const {
+    return VideoSize(mBlockWidth, mBlockHeight);
+}
+
+const Range<int32_t>& VideoCapabilities::getBlockCountRange() const {
+    return mBlockCountRange;
+}
+
+const Range<int64_t>& VideoCapabilities::getBlocksPerSecondRange() const {
+    return mBlocksPerSecondRange;
+}
+
+Range<Rational> VideoCapabilities::getAspectRatioRange(bool blocks) const {
+    return blocks ? mBlockAspectRatioRange : mAspectRatioRange;
+}
+
+void VideoCapabilities::initWithPlatformLimits() {
+    mBitrateRange = BITRATE_RANGE;
+
+    mWidthRange  = VideoSize::GetAllowedDimensionRange();
+    mHeightRange = VideoSize::GetAllowedDimensionRange();
+    mFrameRateRange = FRAME_RATE_RANGE;
+
+    mHorizontalBlockRange = VideoSize::GetAllowedDimensionRange();
+    mVerticalBlockRange   = VideoSize::GetAllowedDimensionRange();
+
+    // full positive ranges are supported as these get calculated
+    mBlockCountRange      = POSITIVE_INT32;
+    mBlocksPerSecondRange = POSITIVE_INT64;
+
+    mBlockAspectRatioRange = POSITIVE_RATIONALS;
+    mAspectRatioRange      = POSITIVE_RATIONALS;
+
+    // YUV 4:2:0 requires 2:2 alignment
+    mWidthAlignment = 2;
+    mHeightAlignment = 2;
+    mBlockWidth = 2;
+    mBlockHeight = 2;
+    mSmallerDimensionUpperLimit = VideoSize::GetAllowedDimensionRange().upper();
+}
+
+std::vector<VideoCapabilities::PerformancePoint>
+        VideoCapabilities::getPerformancePoints(
+        const sp<AMessage> &format) const {
+    std::vector<PerformancePoint> ret;
+    AMessage::Type type;
+    for (int i = 0; i < format->countEntries(); i++) {
+        const char *name = format->getEntryNameAt(i, &type);
+        AString rangeStr;
+        if (!format->findString(name, &rangeStr)) {
+            continue;
+        }
+
+        const std::string key = std::string(name);
+        // looking for: performance-point-WIDTHxHEIGHT-range
+
+        // check none performance point
+        if (key == "performance-point-none" && ret.size() == 0) {
+            // This means that component knowingly did not publish performance points.
+            // This is different from when the component forgot to publish performance
+            // points.
+            return ret;
+        }
+
+        // parse size from key
+        std::regex sizeRegex("performance-point-(.+)-range");
+        std::smatch sizeMatch;
+        if (!std::regex_match(key, sizeMatch, sizeRegex)) {
+            continue;
+        }
+        std::optional<VideoSize> size = VideoSize::ParseSize(sizeMatch[1].str());
+        if (!size || size.value().getWidth() * size.value().getHeight() <= 0) {
+            continue;
+        }
+
+        // parse range from value
+        std::optional<Range<int64_t>> range = Range<int64_t>::Parse(std::string(rangeStr.c_str()));
+        if (!range || range.value().lower() < 0 || range.value().upper() < 0) {
+            continue;
+        }
+
+        PerformancePoint given = PerformancePoint(
+                size.value().getWidth(), size.value().getHeight(), (int32_t)range.value().lower(),
+                (int32_t)range.value().upper(), VideoSize(mBlockWidth, mBlockHeight));
+        PerformancePoint rotated = PerformancePoint(
+                size.value().getHeight(), size.value().getWidth(), (int32_t)range.value().lower(),
+                (int32_t)range.value().upper(), VideoSize(mBlockWidth, mBlockHeight));
+        ret.push_back(given);
+        if (!given.covers(rotated)) {
+            ret.push_back(rotated);
+        }
+    }
+
+    // check if the component specified no performance point indication
+    if (ret.size() == 0) {
+        return ret;
+    }
+
+    // sort reversed by area first, then by frame rate
+    std::sort(ret.begin(), ret.end(), [](const PerformancePoint &a, const PerformancePoint &b) {
+        return -((a.getMaxMacroBlocks() != b.getMaxMacroBlocks()) ?
+                        (a.getMaxMacroBlocks() < b.getMaxMacroBlocks() ? -1 : 1) :
+                (a.getMaxMacroBlockRate() != b.getMaxMacroBlockRate()) ?
+                        (a.getMaxMacroBlockRate() < b.getMaxMacroBlockRate() ? -1 : 1) :
+                (a.getMaxFrameRate() != b.getMaxFrameRate()) ?
+                        (a.getMaxFrameRate() < b.getMaxFrameRate() ? -1 : 1) : 0);
+    });
+
+    return ret;
+}
+
+std::map<VideoSize, Range<int64_t>, VideoSizeCompare> VideoCapabilities
+        ::getMeasuredFrameRates(const sp<AMessage> &format) const {
+    std::map<VideoSize, Range<int64_t>, VideoSizeCompare> ret;
+    AMessage::Type type;
+    for (int i = 0; i < format->countEntries(); i++) {
+        const char *name = format->getEntryNameAt(i, &type);
+        AString rangeStr;
+        if (!format->findString(name, &rangeStr)) {
+            continue;
+        }
+
+        const std::string key = std::string(name);
+        // looking for: measured-frame-rate-WIDTHxHEIGHT-range
+
+        std::regex sizeRegex("measured-frame-rate-(.+)-range");
+        std::smatch sizeMatch;
+        if (!std::regex_match(key, sizeMatch, sizeRegex)) {
+            continue;
+        }
+
+        std::optional<VideoSize> size = VideoSize::ParseSize(sizeMatch[1].str());
+        if (!size || size.value().getWidth() * size.value().getHeight() <= 0) {
+            continue;
+        }
+
+        std::optional<Range<int64_t>> range = Range<int64_t>::Parse(std::string(rangeStr.c_str()));
+        if (!range || range.value().lower() < 0 || range.value().upper() < 0) {
+            continue;
+        }
+
+        ret.emplace(size.value(), range.value());
+    }
+    return ret;
+}
+
+// static
+std::optional<std::pair<Range<int32_t>, Range<int32_t>>> VideoCapabilities
+        ::ParseWidthHeightRanges(const std::string &str) {
+    std::optional<std::pair<VideoSize, VideoSize>> range = VideoSize::ParseSizeRange(str);
+    if (!range) {
+        ALOGW("could not parse size range: %s", str.c_str());
+        return std::nullopt;
+    }
+
+    return std::make_optional(std::pair(
+            Range(range.value().first.getWidth(), range.value().second.getWidth()),
+            Range(range.value().first.getHeight(), range.value().second.getHeight())));
+}
+
+// static
+int32_t VideoCapabilities::EquivalentVP9Level(const sp<AMessage> &format) {
+    int32_t blockSizeWidth = 8;
+    int32_t blockSizeHeight = 8;
+    // VideoSize *blockSizePtr = &VideoSize(8, 8);
+    AString blockSizeStr;
+    if (format->findString("block-size", &blockSizeStr)) {
+        std::optional<VideoSize> parsedBlockSize
+                = VideoSize::ParseSize(std::string(blockSizeStr.c_str()));
+        if (parsedBlockSize) {
+            // blockSize = parsedBlockSize.value();
+            blockSizeWidth = parsedBlockSize.value().getWidth();
+            blockSizeHeight = parsedBlockSize.value().getHeight();
+        }
+    }
+    int32_t BS = blockSizeWidth * blockSizeHeight;
+
+    int32_t FS = 0;
+    AString blockCountRangeStr;
+    if (format->findString("block-count-range", &blockCountRangeStr)) {
+        std::optional<Range<int>> counts = Range<int32_t>::Parse(
+                std::string(blockCountRangeStr.c_str()));
+        if (counts) {
+            FS = BS * counts.value().upper();
+        }
+    }
+
+    int64_t SR = 0;
+    AString blockRatesStr;
+    if (format->findString("blocks-per-second-range", &blockRatesStr)) {
+        std::optional<Range<int64_t>> blockRates
+                = Range<int64_t>::Parse(std::string(blockRatesStr.c_str()));
+        if (blockRates) {
+            // ToDo: Catch the potential overflow issue.
+            SR = BS * blockRates.value().upper();
+        }
+    }
+
+    int32_t D = 0;
+    AString dimensionRangesStr;
+    if (format->findString("size-range", &dimensionRangesStr)) {
+        std::optional<std::pair<Range<int>, Range<int>>> dimensionRanges =
+                ParseWidthHeightRanges(std::string(dimensionRangesStr.c_str()));
+        if (dimensionRanges) {
+            D = std::max(dimensionRanges.value().first.upper(),
+                    dimensionRanges.value().second.upper());
+        }
+    }
+
+    int32_t BR = 0;
+    AString bitrateRangeStr;
+    if (format->findString("bitrate-range", &bitrateRangeStr)) {
+        std::optional<Range<int>> bitRates = Range<int32_t>::Parse(
+                std::string(bitrateRangeStr.c_str()));
+        if (bitRates) {
+            BR = divUp(bitRates.value().upper(), 1000);
+        }
+    }
+
+    if (SR <=      829440 && FS <=    36864 && BR <=    200 && D <=   512)
+        return VP9Level1;
+    if (SR <=     2764800 && FS <=    73728 && BR <=    800 && D <=   768)
+        return VP9Level11;
+    if (SR <=     4608000 && FS <=   122880 && BR <=   1800 && D <=   960)
+        return VP9Level2;
+    if (SR <=     9216000 && FS <=   245760 && BR <=   3600 && D <=  1344)
+        return VP9Level21;
+    if (SR <=    20736000 && FS <=   552960 && BR <=   7200 && D <=  2048)
+        return VP9Level3;
+    if (SR <=    36864000 && FS <=   983040 && BR <=  12000 && D <=  2752)
+        return VP9Level31;
+    if (SR <=    83558400 && FS <=  2228224 && BR <=  18000 && D <=  4160)
+        return VP9Level4;
+    if (SR <=   160432128 && FS <=  2228224 && BR <=  30000 && D <=  4160)
+        return VP9Level41;
+    if (SR <=   311951360 && FS <=  8912896 && BR <=  60000 && D <=  8384)
+        return VP9Level5;
+    if (SR <=   588251136 && FS <=  8912896 && BR <= 120000 && D <=  8384)
+        return VP9Level51;
+    if (SR <=  1176502272 && FS <=  8912896 && BR <= 180000 && D <=  8384)
+        return VP9Level52;
+    if (SR <=  1176502272 && FS <= 35651584 && BR <= 180000 && D <= 16832)
+        return VP9Level6;
+    if (SR <= 2353004544L && FS <= 35651584 && BR <= 240000 && D <= 16832)
+        return VP9Level61;
+    if (SR <= 4706009088L && FS <= 35651584 && BR <= 480000 && D <= 16832)
+        return VP9Level62;
+    // returning largest level
+    return VP9Level62;
+}
+
+void VideoCapabilities::parseFromInfo(const sp<AMessage> &format) {
+    VideoSize blockSize = VideoSize(mBlockWidth, mBlockHeight);
+    VideoSize alignment = VideoSize(mWidthAlignment, mHeightAlignment);
+    std::optional<Range<int32_t>> counts, widths, heights;
+    std::optional<Range<int32_t>> frameRates, bitRates;
+    std::optional<Range<int64_t>> blockRates;
+    std::optional<Range<Rational>> ratios, blockRatios;
+
+    AString blockSizeStr;
+    if (format->findString("block-size", &blockSizeStr)) {
+        std::optional<VideoSize> parsedBlockSize
+                = VideoSize::ParseSize(std::string(blockSizeStr.c_str()));
+        blockSize = parsedBlockSize.value_or(blockSize);
+    }
+    AString alignmentStr;
+    if (format->findString("alignment", &alignmentStr)) {
+        std::optional<VideoSize> parsedAlignment
+            = VideoSize::ParseSize(std::string(alignmentStr.c_str()));
+        alignment = parsedAlignment.value_or(alignment);
+    }
+    AString blockCountRangeStr;
+    if (format->findString("block-count-range", &blockCountRangeStr)) {
+        std::optional<Range<int>> parsedBlockCountRange =
+                Range<int32_t>::Parse(std::string(blockCountRangeStr.c_str()));
+        if (parsedBlockCountRange) {
+            counts = parsedBlockCountRange.value();
+        }
+    }
+    AString blockRatesStr;
+    if (format->findString("blocks-per-second-range", &blockRatesStr)) {
+        blockRates = Range<int64_t>::Parse(std::string(blockRatesStr.c_str()));
+    }
+    mMeasuredFrameRates = getMeasuredFrameRates(format);
+    mPerformancePoints = getPerformancePoints(format);
+    AString sizeRangesStr;
+    if (format->findString("size-range", &sizeRangesStr)) {
+        std::optional<std::pair<Range<int>, Range<int>>> sizeRanges =
+            ParseWidthHeightRanges(std::string(sizeRangesStr.c_str()));
+        if (sizeRanges) {
+            widths = sizeRanges.value().first;
+            heights = sizeRanges.value().second;
+        }
+    }
+    // for now this just means using the smaller max size as 2nd
+    // upper limit.
+    // for now we are keeping the profile specific "width/height
+    // in macroblocks" limits.
+    if (format->contains("feature-can-swap-width-height")) {
+        if (widths && heights) {
+            mSmallerDimensionUpperLimit =
+                std::min(widths.value().upper(), heights.value().upper());
+            widths = heights = widths.value().extend(heights.value());
+        } else {
+            ALOGW("feature can-swap-width-height is best used with size-range");
+            mSmallerDimensionUpperLimit =
+                std::min(mWidthRange.upper(), mHeightRange.upper());
+            mWidthRange = mHeightRange = mWidthRange.extend(mHeightRange);
+        }
+    }
+
+    AString ratioStr;
+    if (format->findString("block-aspect-ratio-range", &ratioStr)) {
+        ratios = Rational::ParseRange(std::string(ratioStr.c_str()));
+    }
+    AString blockRatiosStr;
+    if (format->findString("pixel-aspect-ratio-range", &blockRatiosStr)) {
+        blockRatios = Rational::ParseRange(std::string(blockRatiosStr.c_str()));
+    }
+    AString frameRatesStr;
+    if (format->findString("frame-rate-range", &frameRatesStr)) {
+        frameRates = Range<int32_t>::Parse(std::string(frameRatesStr.c_str()));
+        if (frameRates) {
+            frameRates = frameRates.value().intersect(FRAME_RATE_RANGE);
+            if (frameRates.value().empty()) {
+                ALOGW("frame rate range is out of limits");
+                frameRates = std::nullopt;
+            }
+        }
+    }
+    AString bitRatesStr;
+    if (format->findString("bitrate-range", &bitRatesStr)) {
+        bitRates = Range<int32_t>::Parse(std::string(bitRatesStr.c_str()));
+        if (bitRates) {
+            bitRates = bitRates.value().intersect(BITRATE_RANGE);
+            if (bitRates.value().empty()) {
+                ALOGW("bitrate range is out of limits");
+                bitRates = std::nullopt;
+            }
+        }
+    }
+
+    if (!IsPowerOfTwo(blockSize.getWidth()) || !IsPowerOfTwo(blockSize.getHeight())
+            || !IsPowerOfTwo(alignment.getWidth()) || !IsPowerOfTwo(alignment.getHeight())) {
+        ALOGE("The widths and heights of blockSizes and alignments must be the power of two."
+                " blockSize width: %d; blockSize height: %d;"
+                " alignment width: %d; alignment height: %d.",
+                blockSize.getWidth(), blockSize.getHeight(),
+                alignment.getWidth(), alignment.getHeight());
+        mError |= ERROR_CAPABILITIES_UNRECOGNIZED;
+        return;
+    }
+
+    // update block-size and alignment
+    applyMacroBlockLimits(
+            INT32_MAX, INT32_MAX, INT32_MAX, INT64_MAX,
+            blockSize.getWidth(), blockSize.getHeight(),
+            alignment.getWidth(), alignment.getHeight());
+
+    if ((mError & ERROR_CAPABILITIES_UNSUPPORTED) != 0 || mAllowMbOverride) {
+        // codec supports profiles that we don't know.
+        // Use supplied values clipped to platform limits
+        if (widths) {
+            mWidthRange = VideoSize::GetAllowedDimensionRange().intersect(widths.value());
+        }
+        if (heights) {
+            mHeightRange = VideoSize::GetAllowedDimensionRange().intersect(heights.value());
+        }
+        if (counts) {
+            mBlockCountRange = POSITIVE_INT32.intersect(
+                    counts.value().factor(mBlockWidth * mBlockHeight
+                            / blockSize.getWidth() / blockSize.getHeight()));
+        }
+        if (blockRates) {
+            mBlocksPerSecondRange = POSITIVE_INT64.intersect(
+                    blockRates.value().factor(mBlockWidth * mBlockHeight
+                            / blockSize.getWidth() / blockSize.getHeight()));
+        }
+        if (blockRatios) {
+            mBlockAspectRatioRange = POSITIVE_RATIONALS.intersect(
+                    Rational::ScaleRange(blockRatios.value(),
+                            mBlockHeight / blockSize.getHeight(),
+                            mBlockWidth / blockSize.getWidth()));
+        }
+        if (ratios) {
+            mAspectRatioRange = POSITIVE_RATIONALS.intersect(ratios.value());
+        }
+        if (frameRates) {
+            mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates.value());
+        }
+        if (bitRates) {
+            // only allow bitrate override if unsupported profiles were encountered
+            if ((mError & ERROR_CAPABILITIES_UNSUPPORTED) != 0) {
+                mBitrateRange = BITRATE_RANGE.intersect(bitRates.value());
+            } else {
+                mBitrateRange = mBitrateRange.intersect(bitRates.value());
+            }
+        }
+    } else {
+        // no unsupported profile/levels, so restrict values to known limits
+        if (widths) {
+            mWidthRange = mWidthRange.intersect(widths.value());
+        }
+        if (heights) {
+            mHeightRange = mHeightRange.intersect(heights.value());
+        }
+        if (counts) {
+            mBlockCountRange = mBlockCountRange.intersect(
+                    counts.value().factor(mBlockWidth * mBlockHeight
+                            / blockSize.getWidth() / blockSize.getHeight()));
+        }
+        if (blockRates) {
+            mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
+                    blockRates.value().factor(mBlockWidth * mBlockHeight
+                            / blockSize.getWidth() / blockSize.getHeight()));
+        }
+        if (blockRatios) {
+            mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
+                    Rational::ScaleRange(blockRatios.value(),
+                            mBlockHeight / blockSize.getHeight(),
+                            mBlockWidth / blockSize.getWidth()));
+        }
+        if (ratios) {
+            mAspectRatioRange = mAspectRatioRange.intersect(ratios.value());
+        }
+        if (frameRates) {
+            mFrameRateRange = mFrameRateRange.intersect(frameRates.value());
+        }
+        if (bitRates) {
+            mBitrateRange = mBitrateRange.intersect(bitRates.value());
+        }
+    }
+    updateLimits();
+}
+
+void VideoCapabilities::applyBlockLimits(
+        int32_t blockWidth, int32_t blockHeight,
+        Range<int32_t> counts, Range<int64_t> rates, Range<Rational> ratios) {
+
+    if (!IsPowerOfTwo(blockWidth) || !IsPowerOfTwo(blockHeight)) {
+        ALOGE("blockWidth and blockHeight must be the power of two."
+                " blockWidth: %d; blockHeight: %d", blockWidth, blockHeight);
+        mError |= ERROR_CAPABILITIES_UNRECOGNIZED;
+        return;
+    }
+
+    const int32_t newBlockWidth = std::max(blockWidth, mBlockWidth);
+    const int32_t newBlockHeight = std::max(blockHeight, mBlockHeight);
+
+    // factor will always be a power-of-2
+    int32_t factor =
+        newBlockWidth * newBlockHeight / mBlockWidth / mBlockHeight;
+    if (factor != 1) {
+        mBlockCountRange = mBlockCountRange.factor(factor);
+        mBlocksPerSecondRange = mBlocksPerSecondRange.factor(factor);
+        mBlockAspectRatioRange = Rational::ScaleRange(
+                mBlockAspectRatioRange,
+                newBlockHeight / mBlockHeight,
+                newBlockWidth / mBlockWidth);
+        mHorizontalBlockRange = mHorizontalBlockRange.factor(newBlockWidth / mBlockWidth);
+        mVerticalBlockRange = mVerticalBlockRange.factor(newBlockHeight / mBlockHeight);
+    }
+    factor = newBlockWidth * newBlockHeight / blockWidth / blockHeight;
+    if (factor != 1) {
+        counts = counts.factor(factor);
+        rates = rates.factor((int64_t)factor);
+        ratios = Rational::ScaleRange(
+                ratios, newBlockHeight / blockHeight,
+                newBlockWidth / blockWidth);
+    }
+    mBlockCountRange = mBlockCountRange.intersect(counts);
+    mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(rates);
+    mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(ratios);
+    mBlockWidth = newBlockWidth;
+    mBlockHeight = newBlockHeight;
+}
+
+void VideoCapabilities::applyAlignment(
+        int32_t widthAlignment, int32_t heightAlignment) {
+    if (!IsPowerOfTwo(widthAlignment) || !IsPowerOfTwo(heightAlignment)) {
+        ALOGE("width and height alignments must be the power of two."
+                " widthAlignment: %d; heightAlignment: %d", widthAlignment, heightAlignment);
+        mError |= ERROR_CAPABILITIES_UNRECOGNIZED;
+        return;
+    }
+
+    if (widthAlignment > mBlockWidth || heightAlignment > mBlockHeight) {
+        // maintain assumption that 0 < alignment <= block-size
+        applyBlockLimits(
+                std::max(widthAlignment, mBlockWidth),
+                std::max(heightAlignment, mBlockHeight),
+                POSITIVE_INT32, POSITIVE_INT64, POSITIVE_RATIONALS);
+    }
+
+    mWidthAlignment = std::max(widthAlignment, mWidthAlignment);
+    mHeightAlignment = std::max(heightAlignment, mHeightAlignment);
+
+    mWidthRange = mWidthRange.align(mWidthAlignment);
+    mHeightRange = mHeightRange.align(mHeightAlignment);
+}
+
+void VideoCapabilities::updateLimits() {
+    // pixels -> blocks <- counts
+    mHorizontalBlockRange = mHorizontalBlockRange.intersect(
+            mWidthRange.factor(mBlockWidth));
+    mHorizontalBlockRange = mHorizontalBlockRange.intersect(
+            Range(  mBlockCountRange.lower() / mVerticalBlockRange.upper(),
+                    mBlockCountRange.upper() / mVerticalBlockRange.lower()));
+    mVerticalBlockRange = mVerticalBlockRange.intersect(
+            mHeightRange.factor(mBlockHeight));
+    mVerticalBlockRange = mVerticalBlockRange.intersect(
+            Range(  mBlockCountRange.lower() / mHorizontalBlockRange.upper(),
+                    mBlockCountRange.upper() / mHorizontalBlockRange.lower()));
+    mBlockCountRange = mBlockCountRange.intersect(
+            Range(  mHorizontalBlockRange.lower()
+                            * mVerticalBlockRange.lower(),
+                    mHorizontalBlockRange.upper()
+                            * mVerticalBlockRange.upper()));
+    mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
+            Rational(mHorizontalBlockRange.lower(), mVerticalBlockRange.upper()),
+            Rational(mHorizontalBlockRange.upper(), mVerticalBlockRange.lower()));
+
+    // blocks -> pixels
+    mWidthRange = mWidthRange.intersect(
+            (mHorizontalBlockRange.lower() - 1) * mBlockWidth + mWidthAlignment,
+            mHorizontalBlockRange.upper() * mBlockWidth);
+    mHeightRange = mHeightRange.intersect(
+            (mVerticalBlockRange.lower() - 1) * mBlockHeight + mHeightAlignment,
+            mVerticalBlockRange.upper() * mBlockHeight);
+    mAspectRatioRange = mAspectRatioRange.intersect(
+            Rational(mWidthRange.lower(), mHeightRange.upper()),
+            Rational(mWidthRange.upper(), mHeightRange.lower()));
+
+    mSmallerDimensionUpperLimit = std::min(
+            mSmallerDimensionUpperLimit,
+            std::min(mWidthRange.upper(), mHeightRange.upper()));
+
+    // blocks -> rate
+    mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
+            mBlockCountRange.lower() * (int64_t)mFrameRateRange.lower(),
+            mBlockCountRange.upper() * (int64_t)mFrameRateRange.upper());
+    mFrameRateRange = mFrameRateRange.intersect(
+            (int32_t)(mBlocksPerSecondRange.lower()
+                    / mBlockCountRange.upper()),
+            (int32_t)(mBlocksPerSecondRange.upper()
+                    / (double)mBlockCountRange.lower()));
+}
+
+void VideoCapabilities::applyMacroBlockLimits(
+        int32_t maxHorizontalBlocks, int32_t maxVerticalBlocks,
+        int32_t maxBlocks, int64_t maxBlocksPerSecond,
+        int32_t blockWidth, int32_t blockHeight,
+        int32_t widthAlignment, int32_t heightAlignment) {
+    applyMacroBlockLimits(
+            1 /* minHorizontalBlocks */, 1 /* minVerticalBlocks */,
+            maxHorizontalBlocks, maxVerticalBlocks,
+            maxBlocks, maxBlocksPerSecond,
+            blockWidth, blockHeight, widthAlignment, heightAlignment);
+}
+
+void VideoCapabilities::applyMacroBlockLimits(
+        int32_t minHorizontalBlocks, int32_t minVerticalBlocks,
+        int32_t maxHorizontalBlocks, int32_t maxVerticalBlocks,
+        int32_t maxBlocks, int64_t maxBlocksPerSecond,
+        int32_t blockWidth, int32_t blockHeight,
+        int32_t widthAlignment, int32_t heightAlignment) {
+    applyAlignment(widthAlignment, heightAlignment);
+    applyBlockLimits(
+            blockWidth, blockHeight, Range((int32_t)1, maxBlocks),
+            Range((int64_t)1, maxBlocksPerSecond),
+            Range(Rational(1, maxVerticalBlocks), Rational(maxHorizontalBlocks, 1)));
+    mHorizontalBlockRange =
+            mHorizontalBlockRange.intersect(
+                    divUp(minHorizontalBlocks, (mBlockWidth / blockWidth)),
+                    maxHorizontalBlocks / (mBlockWidth / blockWidth));
+    mVerticalBlockRange =
+            mVerticalBlockRange.intersect(
+                    divUp(minVerticalBlocks, (mBlockHeight / blockHeight)),
+                    maxVerticalBlocks / (mBlockHeight / blockHeight));
+}
+
+void VideoCapabilities::applyLevelLimits() {
+    int64_t maxBlocksPerSecond = 0;
+    int32_t maxBlocks = 0;
+    int32_t maxBps = 0;
+    int32_t maxDPBBlocks = 0;
+
+    int errors = ERROR_CAPABILITIES_NONE_SUPPORTED;
+    const char *mediaType = mMediaType.c_str();
+    if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_AVC)) {
+        maxBlocks = 99;
+        maxBlocksPerSecond = 1485;
+        maxBps = 64000;
+        maxDPBBlocks = 396;
+        for (ProfileLevel profileLevel: mProfileLevels) {
+            int32_t MBPS = 0, FS = 0, BR = 0, DPB = 0;
+            bool supported = true;
+            switch (profileLevel.mLevel) {
+                case AVCLevel1:
+                    MBPS =     1485; FS =     99; BR =     64; DPB =    396; break;
+                case AVCLevel1b:
+                    MBPS =     1485; FS =     99; BR =    128; DPB =    396; break;
+                case AVCLevel11:
+                    MBPS =     3000; FS =    396; BR =    192; DPB =    900; break;
+                case AVCLevel12:
+                    MBPS =     6000; FS =    396; BR =    384; DPB =   2376; break;
+                case AVCLevel13:
+                    MBPS =    11880; FS =    396; BR =    768; DPB =   2376; break;
+                case AVCLevel2:
+                    MBPS =    11880; FS =    396; BR =   2000; DPB =   2376; break;
+                case AVCLevel21:
+                    MBPS =    19800; FS =    792; BR =   4000; DPB =   4752; break;
+                case AVCLevel22:
+                    MBPS =    20250; FS =   1620; BR =   4000; DPB =   8100; break;
+                case AVCLevel3:
+                    MBPS =    40500; FS =   1620; BR =  10000; DPB =   8100; break;
+                case AVCLevel31:
+                    MBPS =   108000; FS =   3600; BR =  14000; DPB =  18000; break;
+                case AVCLevel32:
+                    MBPS =   216000; FS =   5120; BR =  20000; DPB =  20480; break;
+                case AVCLevel4:
+                    MBPS =   245760; FS =   8192; BR =  20000; DPB =  32768; break;
+                case AVCLevel41:
+                    MBPS =   245760; FS =   8192; BR =  50000; DPB =  32768; break;
+                case AVCLevel42:
+                    MBPS =   522240; FS =   8704; BR =  50000; DPB =  34816; break;
+                case AVCLevel5:
+                    MBPS =   589824; FS =  22080; BR = 135000; DPB = 110400; break;
+                case AVCLevel51:
+                    MBPS =   983040; FS =  36864; BR = 240000; DPB = 184320; break;
+                case AVCLevel52:
+                    MBPS =  2073600; FS =  36864; BR = 240000; DPB = 184320; break;
+                case AVCLevel6:
+                    MBPS =  4177920; FS = 139264; BR = 240000; DPB = 696320; break;
+                case AVCLevel61:
+                    MBPS =  8355840; FS = 139264; BR = 480000; DPB = 696320; break;
+                case AVCLevel62:
+                    MBPS = 16711680; FS = 139264; BR = 800000; DPB = 696320; break;
+                default:
+                    ALOGW("Unrecognized level %d for %s", profileLevel.mLevel, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            switch (profileLevel.mProfile) {
+                case AVCProfileConstrainedHigh:
+                case AVCProfileHigh:
+                    BR *= 1250; break;
+                case AVCProfileHigh10:
+                    BR *= 3000; break;
+                case AVCProfileExtended:
+                case AVCProfileHigh422:
+                case AVCProfileHigh444:
+                    ALOGW("Unsupported profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+                    supported = false;
+                    FALLTHROUGH_INTENDED;
+                    // fall through - treat as base profile
+                case AVCProfileConstrainedBaseline:
+                    FALLTHROUGH_INTENDED;
+                case AVCProfileBaseline:
+                    FALLTHROUGH_INTENDED;
+                case AVCProfileMain:
+                    BR *= 1000; break;
+                default:
+                    ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+                    BR *= 1000;
+            }
+            if (supported) {
+                errors &= ~ERROR_CAPABILITIES_NONE_SUPPORTED;
+            }
+            maxBlocksPerSecond = std::max((int64_t)MBPS, maxBlocksPerSecond);
+            maxBlocks = std::max(FS, maxBlocks);
+            maxBps = std::max(BR, maxBps);
+            maxDPBBlocks = std::max(maxDPBBlocks, DPB);
+        }
+
+        int32_t maxLengthInBlocks = (int32_t)(std::sqrt(8 * maxBlocks));
+        applyMacroBlockLimits(
+                maxLengthInBlocks, maxLengthInBlocks,
+                maxBlocks, maxBlocksPerSecond,
+                16 /* blockWidth */, 16 /* blockHeight */,
+                1 /* widthAlignment */, 1 /* heightAlignment */);
+    } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_MPEG2)) {
+        int32_t maxWidth = 11, maxHeight = 9, maxRate = 15;
+        maxBlocks = 99;
+        maxBlocksPerSecond = 1485;
+        maxBps = 64000;
+        for (ProfileLevel profileLevel: mProfileLevels) {
+            int32_t MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0;
+            bool supported = true;
+            switch (profileLevel.mProfile) {
+                case MPEG2ProfileSimple:
+                    switch (profileLevel.mLevel) {
+                        case MPEG2LevelML:
+                            FR = 30; W = 45; H =  36; MBPS =  40500; FS =  1620; BR =  15000; break;
+                        default:
+                            ALOGW("Unrecognized profile/level %d/%d for %s",
+                                    profileLevel.mProfile, profileLevel.mLevel, mediaType);
+                            errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+                    }
+                    break;
+                case MPEG2ProfileMain:
+                    switch (profileLevel.mLevel) {
+                        case MPEG2LevelLL:
+                            FR = 30; W = 22; H =  18; MBPS =  11880; FS =   396; BR =  4000; break;
+                        case MPEG2LevelML:
+                            FR = 30; W = 45; H =  36; MBPS =  40500; FS =  1620; BR = 15000; break;
+                        case MPEG2LevelH14:
+                            FR = 60; W = 90; H =  68; MBPS = 183600; FS =  6120; BR = 60000; break;
+                        case MPEG2LevelHL:
+                            FR = 60; W = 120; H = 68; MBPS = 244800; FS =  8160; BR = 80000; break;
+                        case MPEG2LevelHP:
+                            FR = 60; W = 120; H = 68; MBPS = 489600; FS =  8160; BR = 80000; break;
+                        default:
+                            ALOGW("Unrecognized profile/level %d / %d for %s",
+                                    profileLevel.mProfile, profileLevel.mLevel, mediaType);
+                            errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+                    }
+                    break;
+                case MPEG2Profile422:
+                case MPEG2ProfileSNR:
+                case MPEG2ProfileSpatial:
+                case MPEG2ProfileHigh:
+                    ALOGW("Unsupported profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNSUPPORTED;
+                    supported = false;
+                    break;
+                default:
+                    ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            if (supported) {
+                errors &= ~ERROR_CAPABILITIES_NONE_SUPPORTED;
+            }
+            maxBlocksPerSecond = std::max((int64_t)MBPS, maxBlocksPerSecond);
+            maxBlocks = std::max(FS, maxBlocks);
+            maxBps = std::max(BR * 1000, maxBps);
+            maxWidth = std::max(W, maxWidth);
+            maxHeight = std::max(H, maxHeight);
+            maxRate = std::max(FR, maxRate);
+        }
+        applyMacroBlockLimits(maxWidth, maxHeight,
+                maxBlocks, maxBlocksPerSecond,
+                16 /* blockWidth */, 16 /* blockHeight */,
+                1 /* widthAlignment */, 1 /* heightAlignment */);
+        mFrameRateRange = mFrameRateRange.intersect(12, maxRate);
+    } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_MPEG4)) {
+        int32_t maxWidth = 11, maxHeight = 9, maxRate = 15;
+        maxBlocks = 99;
+        maxBlocksPerSecond = 1485;
+        maxBps = 64000;
+        for (ProfileLevel profileLevel: mProfileLevels) {
+            int32_t MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0;
+            bool strict = false; // true: W, H and FR are individual max limits
+            bool supported = true;
+            switch (profileLevel.mProfile) {
+                case MPEG4ProfileSimple:
+                    switch (profileLevel.mLevel) {
+                        case MPEG4Level0:
+                            strict = true;
+                            FR = 15; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
+                        case MPEG4Level1:
+                            FR = 30; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
+                        case MPEG4Level0b:
+                            strict = true;
+                            FR = 15; W = 11; H =  9; MBPS =  1485; FS =  99; BR = 128; break;
+                        case MPEG4Level2:
+                            FR = 30; W = 22; H = 18; MBPS =  5940; FS = 396; BR = 128; break;
+                        case MPEG4Level3:
+                            FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384; break;
+                        case MPEG4Level4a:
+                            FR = 30; W = 40; H = 30; MBPS = 36000; FS = 1200; BR = 4000; break;
+                        case MPEG4Level5:
+                            FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 8000; break;
+                        case MPEG4Level6:
+                            FR = 30; W = 80; H = 45; MBPS = 108000; FS = 3600; BR = 12000; break;
+                        default:
+                            ALOGW("Unrecognized profile/level %d/%d for %s",
+                                    profileLevel.mProfile, profileLevel.mLevel, mediaType);
+                            errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+                    }
+                    break;
+                case MPEG4ProfileAdvancedSimple:
+                    switch (profileLevel.mLevel) {
+                        case MPEG4Level0:
+                        case MPEG4Level1:
+                            FR = 30; W = 11; H =  9; MBPS =  2970; FS =   99; BR =  128; break;
+                        case MPEG4Level2:
+                            FR = 30; W = 22; H = 18; MBPS =  5940; FS =  396; BR =  384; break;
+                        case MPEG4Level3:
+                            FR = 30; W = 22; H = 18; MBPS = 11880; FS =  396; BR =  768; break;
+                        case MPEG4Level3b:
+                            FR = 30; W = 22; H = 18; MBPS = 11880; FS =  396; BR = 1500; break;
+                        case MPEG4Level4:
+                            FR = 30; W = 44; H = 36; MBPS = 23760; FS =  792; BR = 3000; break;
+                        case MPEG4Level5:
+                            FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 8000; break;
+                        default:
+                            ALOGW("Unrecognized profile/level %d/%d for %s",
+                                    profileLevel.mProfile, profileLevel.mLevel, mediaType);
+                            errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+                    }
+                    break;
+                case MPEG4ProfileMain:             // 2-4
+                case MPEG4ProfileNbit:             // 2
+                case MPEG4ProfileAdvancedRealTime: // 1-4
+                case MPEG4ProfileCoreScalable:     // 1-3
+                case MPEG4ProfileAdvancedCoding:   // 1-4
+                case MPEG4ProfileCore:             // 1-2
+                case MPEG4ProfileAdvancedCore:     // 1-4
+                case MPEG4ProfileSimpleScalable:   // 0-2
+                case MPEG4ProfileHybrid:           // 1-2
+
+                // Studio profiles are not supported by our codecs.
+
+                // Only profiles that can decode simple object types are considered.
+                // The following profiles are not able to.
+                case MPEG4ProfileBasicAnimated:    // 1-2
+                case MPEG4ProfileScalableTexture:  // 1
+                case MPEG4ProfileSimpleFace:       // 1-2
+                case MPEG4ProfileAdvancedScalable: // 1-3
+                case MPEG4ProfileSimpleFBA:        // 1-2
+                    ALOGV("Unsupported profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNSUPPORTED;
+                    supported = false;
+                    break;
+                default:
+                    ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            if (supported) {
+                errors &= ~ERROR_CAPABILITIES_NONE_SUPPORTED;
+            }
+            maxBlocksPerSecond = std::max((int64_t)MBPS, maxBlocksPerSecond);
+            maxBlocks = std::max(FS, maxBlocks);
+            maxBps = std::max(BR * 1000, maxBps);
+            if (strict) {
+                maxWidth = std::max(W, maxWidth);
+                maxHeight = std::max(H, maxHeight);
+                maxRate = std::max(FR, maxRate);
+            } else {
+                // assuming max 60 fps frame rate and 1:2 aspect ratio
+                int32_t maxDim = (int32_t)std::sqrt(2 * FS);
+                maxWidth = std::max(maxDim, maxWidth);
+                maxHeight = std::max(maxDim, maxHeight);
+                maxRate = std::max(std::max(FR, 60), maxRate);
+            }
+        }
+        applyMacroBlockLimits(maxWidth, maxHeight,
+                maxBlocks, maxBlocksPerSecond,
+                16 /* blockWidth */, 16 /* blockHeight */,
+                1 /* widthAlignment */, 1 /* heightAlignment */);
+        mFrameRateRange = mFrameRateRange.intersect(12, maxRate);
+    } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_H263)) {
+        int32_t maxWidth = 11, maxHeight = 9, maxRate = 15;
+        int32_t minWidth = maxWidth, minHeight = maxHeight;
+        int32_t minAlignment = 16;
+        maxBlocks = 99;
+        maxBlocksPerSecond = 1485;
+        maxBps = 64000;
+        for (ProfileLevel profileLevel: mProfileLevels) {
+            int32_t MBPS = 0, BR = 0, FR = 0, W = 0, H = 0, minW = minWidth, minH = minHeight;
+            bool strict = false; // true: support only sQCIF, QCIF (maybe CIF)
+            switch (profileLevel.mLevel) {
+                case H263Level10:
+                    strict = true; // only supports sQCIF & QCIF
+                    FR = 15; W = 11; H =  9; BR =   1; MBPS =  W * H * FR; break;
+                case H263Level20:
+                    strict = true; // only supports sQCIF, QCIF & CIF
+                    FR = 30; W = 22; H = 18; BR =   2; MBPS =  W * H * 15; break;
+                case H263Level30:
+                    strict = true; // only supports sQCIF, QCIF & CIF
+                    FR = 30; W = 22; H = 18; BR =   6; MBPS =  W * H * FR; break;
+                case H263Level40:
+                    strict = true; // only supports sQCIF, QCIF & CIF
+                    FR = 30; W = 22; H = 18; BR =  32; MBPS =  W * H * FR; break;
+                case H263Level45:
+                    // only implies level 10 support
+                    strict = profileLevel.mProfile == H263ProfileBaseline
+                            || profileLevel.mProfile ==
+                                    H263ProfileBackwardCompatible;
+                    if (!strict) {
+                        minW = 1; minH = 1; minAlignment = 4;
+                    }
+                    FR = 15; W = 11; H =  9; BR =   2; MBPS =  W * H * FR; break;
+                case H263Level50:
+                    // only supports 50fps for H > 15
+                    minW = 1; minH = 1; minAlignment = 4;
+                    FR = 60; W = 22; H = 18; BR =  64; MBPS =  W * H * 50; break;
+                case H263Level60:
+                    // only supports 50fps for H > 15
+                    minW = 1; minH = 1; minAlignment = 4;
+                    FR = 60; W = 45; H = 18; BR = 128; MBPS =  W * H * 50; break;
+                case H263Level70:
+                    // only supports 50fps for H > 30
+                    minW = 1; minH = 1; minAlignment = 4;
+                    FR = 60; W = 45; H = 36; BR = 256; MBPS =  W * H * 50; break;
+                default:
+                    ALOGW("Unrecognized profile/level %d/%d for %s",
+                            profileLevel.mProfile, profileLevel.mLevel, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            switch (profileLevel.mProfile) {
+                case H263ProfileBackwardCompatible:
+                case H263ProfileBaseline:
+                case H263ProfileH320Coding:
+                case H263ProfileHighCompression:
+                case H263ProfileHighLatency:
+                case H263ProfileInterlace:
+                case H263ProfileInternet:
+                case H263ProfileISWV2:
+                case H263ProfileISWV3:
+                    break;
+                default:
+                    ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            if (strict) {
+                // Strict levels define sub-QCIF min size and enumerated sizes. We cannot
+                // express support for "only sQCIF & QCIF (& CIF)" using VideoCapabilities
+                // but we can express "only QCIF (& CIF)", so set minimume size at QCIF.
+                // minW = 8; minH = 6;
+                minW = 11; minH = 9;
+            } else {
+                // any support for non-strict levels (including unrecognized profiles or
+                // levels) allow custom frame size support beyond supported limits
+                // (other than bitrate)
+                mAllowMbOverride = true;
+            }
+            errors &= ~ERROR_CAPABILITIES_NONE_SUPPORTED;
+            maxBlocksPerSecond = std::max((int64_t)MBPS, maxBlocksPerSecond);
+            maxBlocks = std::max(W * H, maxBlocks);
+            maxBps = std::max(BR * 64000, maxBps);
+            maxWidth = std::max(W, maxWidth);
+            maxHeight = std::max(H, maxHeight);
+            maxRate = std::max(FR, maxRate);
+            minWidth = std::min(minW, minWidth);
+            minHeight = std::min(minH, minHeight);
+        }
+        // unless we encountered custom frame size support, limit size to QCIF and CIF
+        // using aspect ratio.
+        if (!mAllowMbOverride) {
+            mBlockAspectRatioRange =
+                Range(Rational(11, 9), Rational(11, 9));
+        }
+        applyMacroBlockLimits(
+                minWidth, minHeight,
+                maxWidth, maxHeight,
+                maxBlocks, maxBlocksPerSecond,
+                16 /* blockWidth */, 16 /* blockHeight */,
+                minAlignment /* widthAlignment */, minAlignment /* heightAlignment */);
+        mFrameRateRange = Range(1, maxRate);
+    } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_VP8)) {
+        maxBlocks = INT_MAX;
+        maxBlocksPerSecond = INT_MAX;
+
+        // TODO: set to 100Mbps for now, need a number for VP8
+        maxBps = 100000000;
+
+        // profile levels are not indicative for VPx, but verify
+        // them nonetheless
+        for (ProfileLevel profileLevel: mProfileLevels) {
+            switch (profileLevel.mLevel) {
+                case VP8Level_Version0:
+                case VP8Level_Version1:
+                case VP8Level_Version2:
+                case VP8Level_Version3:
+                    break;
+                default:
+                    ALOGW("Unrecognized level %d for %s", profileLevel.mLevel, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            switch (profileLevel.mProfile) {
+                case VP8ProfileMain:
+                    break;
+                default:
+                    ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            errors &= ~ERROR_CAPABILITIES_NONE_SUPPORTED;
+        }
+
+        const int32_t blockSize = 16;
+        applyMacroBlockLimits(SHRT_MAX, SHRT_MAX,
+                maxBlocks, maxBlocksPerSecond, blockSize, blockSize,
+                1 /* widthAlignment */, 1 /* heightAlignment */);
+    } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_VP9)) {
+        maxBlocksPerSecond = 829440;
+        maxBlocks = 36864;
+        maxBps = 200000;
+        int32_t maxDim = 512;
+
+        for (ProfileLevel profileLevel: mProfileLevels) {
+            int64_t SR = 0; // luma sample rate
+            int32_t FS = 0;  // luma picture size
+            int32_t BR = 0;  // bit rate kbps
+            int32_t D = 0;   // luma dimension
+            switch (profileLevel.mLevel) {
+                case VP9Level1:
+                    SR =      829440; FS =    36864; BR =    200; D =   512; break;
+                case VP9Level11:
+                    SR =     2764800; FS =    73728; BR =    800; D =   768; break;
+                case VP9Level2:
+                    SR =     4608000; FS =   122880; BR =   1800; D =   960; break;
+                case VP9Level21:
+                    SR =     9216000; FS =   245760; BR =   3600; D =  1344; break;
+                case VP9Level3:
+                    SR =    20736000; FS =   552960; BR =   7200; D =  2048; break;
+                case VP9Level31:
+                    SR =    36864000; FS =   983040; BR =  12000; D =  2752; break;
+                case VP9Level4:
+                    SR =    83558400; FS =  2228224; BR =  18000; D =  4160; break;
+                case VP9Level41:
+                    SR =   160432128; FS =  2228224; BR =  30000; D =  4160; break;
+                case VP9Level5:
+                    SR =   311951360; FS =  8912896; BR =  60000; D =  8384; break;
+                case VP9Level51:
+                    SR =   588251136; FS =  8912896; BR = 120000; D =  8384; break;
+                case VP9Level52:
+                    SR =  1176502272; FS =  8912896; BR = 180000; D =  8384; break;
+                case VP9Level6:
+                    SR =  1176502272; FS = 35651584; BR = 180000; D = 16832; break;
+                case VP9Level61:
+                    SR = 2353004544L; FS = 35651584; BR = 240000; D = 16832; break;
+                case VP9Level62:
+                    SR = 4706009088L; FS = 35651584; BR = 480000; D = 16832; break;
+                default:
+                    ALOGW("Unrecognized level %d for %s", profileLevel.mLevel, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            switch (profileLevel.mProfile) {
+                case VP9Profile0:
+                case VP9Profile1:
+                case VP9Profile2:
+                case VP9Profile3:
+                case VP9Profile2HDR:
+                case VP9Profile3HDR:
+                case VP9Profile2HDR10Plus:
+                case VP9Profile3HDR10Plus:
+                    break;
+                default:
+                    ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            errors &= ~ERROR_CAPABILITIES_NONE_SUPPORTED;
+            maxBlocksPerSecond = std::max(SR, maxBlocksPerSecond);
+            maxBlocks = std::max(FS, maxBlocks);
+            maxBps = std::max(BR * 1000, maxBps);
+            maxDim = std::max(D, maxDim);
+        }
+
+        const int32_t blockSize = 8;
+        int32_t maxLengthInBlocks = divUp(maxDim, blockSize);
+        maxBlocks = divUp(maxBlocks, blockSize * blockSize);
+        maxBlocksPerSecond = divUp(maxBlocksPerSecond, blockSize * (int64_t)blockSize);
+
+        applyMacroBlockLimits(
+                maxLengthInBlocks, maxLengthInBlocks,
+                maxBlocks, maxBlocksPerSecond,
+                blockSize, blockSize,
+                1 /* widthAlignment */, 1 /* heightAlignment */);
+    } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_HEVC)) {
+        // CTBs are at least 8x8 so use 8x8 block size
+        maxBlocks = 36864 >> 6; // 192x192 pixels == 576 8x8 blocks
+        maxBlocksPerSecond = maxBlocks * 15;
+        maxBps = 128000;
+        for (ProfileLevel profileLevel: mProfileLevels) {
+            double FR = 0;
+            int32_t FS = 0, BR = 0;
+            switch (profileLevel.mLevel) {
+                /* The HEVC spec talks only in a very convoluted manner about the
+                    existence of levels 1-3.1 for High tier, which could also be
+                    understood as 'decoders and encoders should treat these levels
+                    as if they were Main tier', so we do that. */
+                case HEVCMainTierLevel1:
+                case HEVCHighTierLevel1:
+                    FR =    15; FS =    36864; BR =    128; break;
+                case HEVCMainTierLevel2:
+                case HEVCHighTierLevel2:
+                    FR =    30; FS =   122880; BR =   1500; break;
+                case HEVCMainTierLevel21:
+                case HEVCHighTierLevel21:
+                    FR =    30; FS =   245760; BR =   3000; break;
+                case HEVCMainTierLevel3:
+                case HEVCHighTierLevel3:
+                    FR =    30; FS =   552960; BR =   6000; break;
+                case HEVCMainTierLevel31:
+                case HEVCHighTierLevel31:
+                    FR = 33.75; FS =   983040; BR =  10000; break;
+                case HEVCMainTierLevel4:
+                    FR =    30; FS =  2228224; BR =  12000; break;
+                case HEVCHighTierLevel4:
+                    FR =    30; FS =  2228224; BR =  30000; break;
+                case HEVCMainTierLevel41:
+                    FR =    60; FS =  2228224; BR =  20000; break;
+                case HEVCHighTierLevel41:
+                    FR =    60; FS =  2228224; BR =  50000; break;
+                case HEVCMainTierLevel5:
+                    FR =    30; FS =  8912896; BR =  25000; break;
+                case HEVCHighTierLevel5:
+                    FR =    30; FS =  8912896; BR = 100000; break;
+                case HEVCMainTierLevel51:
+                    FR =    60; FS =  8912896; BR =  40000; break;
+                case HEVCHighTierLevel51:
+                    FR =    60; FS =  8912896; BR = 160000; break;
+                case HEVCMainTierLevel52:
+                    FR =   120; FS =  8912896; BR =  60000; break;
+                case HEVCHighTierLevel52:
+                    FR =   120; FS =  8912896; BR = 240000; break;
+                case HEVCMainTierLevel6:
+                    FR =    30; FS = 35651584; BR =  60000; break;
+                case HEVCHighTierLevel6:
+                    FR =    30; FS = 35651584; BR = 240000; break;
+                case HEVCMainTierLevel61:
+                    FR =    60; FS = 35651584; BR = 120000; break;
+                case HEVCHighTierLevel61:
+                    FR =    60; FS = 35651584; BR = 480000; break;
+                case HEVCMainTierLevel62:
+                    FR =   120; FS = 35651584; BR = 240000; break;
+                case HEVCHighTierLevel62:
+                    FR =   120; FS = 35651584; BR = 800000; break;
+                default:
+                    ALOGW("Unrecognized level %d for %s", profileLevel.mLevel, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            switch (profileLevel.mProfile) {
+                case HEVCProfileMain:
+                case HEVCProfileMain10:
+                case HEVCProfileMainStill:
+                case HEVCProfileMain10HDR10:
+                case HEVCProfileMain10HDR10Plus:
+                    break;
+                default:
+                    ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+
+            /* DPB logic:
+            if      (width * height <= FS / 4)    DPB = 16;
+            else if (width * height <= FS / 2)    DPB = 12;
+            else if (width * height <= FS * 0.75) DPB = 8;
+            else                                  DPB = 6;
+            */
+
+            FS >>= 6; // convert pixels to blocks
+            errors &= ~ERROR_CAPABILITIES_NONE_SUPPORTED;
+            maxBlocksPerSecond = std::max((int64_t)(FR * FS), maxBlocksPerSecond);
+            maxBlocks = std::max(FS, maxBlocks);
+            maxBps = std::max(1000 * BR, maxBps);
+        }
+
+        int32_t maxLengthInBlocks = (int32_t)(std::sqrt(8 * maxBlocks));
+        applyMacroBlockLimits(
+                maxLengthInBlocks, maxLengthInBlocks,
+                maxBlocks, maxBlocksPerSecond,
+                8 /* blockWidth */, 8 /* blockHeight */,
+                1 /* widthAlignment */, 1 /* heightAlignment */);
+    } else if (base::EqualsIgnoreCase(mMediaType, MIMETYPE_VIDEO_AV1)) {
+        maxBlocksPerSecond = 829440;
+        maxBlocks = 36864;
+        maxBps = 200000;
+        int32_t maxDim = 512;
+
+        // Sample rate, Picture Size, Bit rate and luma dimension for AV1 Codec,
+        // corresponding to the definitions in
+        // "AV1 Bitstream & Decoding Process Specification", Annex A
+        // found at https://aomedia.org/av1-bitstream-and-decoding-process-specification/
+        for (ProfileLevel profileLevel: mProfileLevels) {
+            int64_t SR = 0; // luma sample rate
+            int32_t FS = 0;  // luma picture size
+            int32_t BR = 0;  // bit rate kbps
+            int32_t D = 0;   // luma D
+            switch (profileLevel.mLevel) {
+                case AV1Level2:
+                    SR =     5529600; FS =   147456; BR =   1500; D =  2048; break;
+                case AV1Level21:
+                case AV1Level22:
+                case AV1Level23:
+                    SR =    10454400; FS =   278784; BR =   3000; D =  2816; break;
+
+                case AV1Level3:
+                    SR =    24969600; FS =   665856; BR =   6000; D =  4352; break;
+                case AV1Level31:
+                case AV1Level32:
+                case AV1Level33:
+                    SR =    39938400; FS =  1065024; BR =  10000; D =  5504; break;
+
+                case AV1Level4:
+                    SR =    77856768; FS =  2359296; BR =  12000; D =  6144; break;
+                case AV1Level41:
+                case AV1Level42:
+                case AV1Level43:
+                    SR =   155713536; FS =  2359296; BR =  20000; D =  6144; break;
+
+                case AV1Level5:
+                    SR =   273715200; FS =  8912896; BR =  30000; D =  8192; break;
+                case AV1Level51:
+                    SR =   547430400; FS =  8912896; BR =  40000; D =  8192; break;
+                case AV1Level52:
+                    SR =  1094860800; FS =  8912896; BR =  60000; D =  8192; break;
+                case AV1Level53:
+                    SR =  1176502272; FS =  8912896; BR =  60000; D =  8192; break;
+
+                case AV1Level6:
+                    SR =  1176502272; FS = 35651584; BR =  60000; D = 16384; break;
+                case AV1Level61:
+                    SR = 2189721600L; FS = 35651584; BR = 100000; D = 16384; break;
+                case AV1Level62:
+                    SR = 4379443200L; FS = 35651584; BR = 160000; D = 16384; break;
+                case AV1Level63:
+                    SR = 4706009088L; FS = 35651584; BR = 160000; D = 16384; break;
+
+                default:
+                    ALOGW("Unrecognized level %d for %s", profileLevel.mLevel, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            switch (profileLevel.mProfile) {
+                case AV1ProfileMain8:
+                case AV1ProfileMain10:
+                case AV1ProfileMain10HDR10:
+                case AV1ProfileMain10HDR10Plus:
+                    break;
+                default:
+                    ALOGW("Unrecognized profile %d for %s", profileLevel.mProfile, mediaType);
+                    errors |= ERROR_CAPABILITIES_UNRECOGNIZED;
+            }
+            errors &= ~ERROR_CAPABILITIES_NONE_SUPPORTED;
+            maxBlocksPerSecond = std::max(SR, maxBlocksPerSecond);
+            maxBlocks = std::max(FS, maxBlocks);
+            maxBps = std::max(BR * 1000, maxBps);
+            maxDim = std::max(D, maxDim);
+        }
+
+        const int32_t blockSize = 8;
+        int32_t maxLengthInBlocks = divUp(maxDim, blockSize);
+        maxBlocks = divUp(maxBlocks, blockSize * blockSize);
+        maxBlocksPerSecond = divUp(maxBlocksPerSecond, blockSize * (int64_t)blockSize);
+        applyMacroBlockLimits(
+                maxLengthInBlocks, maxLengthInBlocks,
+                maxBlocks, maxBlocksPerSecond,
+                blockSize, blockSize,
+                1 /* widthAlignment */, 1 /* heightAlignment */);
+    } else {
+        ALOGW("Unsupported mime %s", mediaType);
+        // using minimal bitrate here.  should be overridden by
+        // info from media_codecs.xml
+        maxBps = 64000;
+        errors |= ERROR_CAPABILITIES_UNSUPPORTED;
+    }
+    mBitrateRange = Range(1, maxBps);
+    mError |= errors;
+}
+
+}  // namespace android
\ No newline at end of file
diff --git a/media/libmedia/include/media/CodecCapabilities.h b/media/libmedia/include/media/CodecCapabilities.h
index 570c8b5..700373a 100644
--- a/media/libmedia/include/media/CodecCapabilities.h
+++ b/media/libmedia/include/media/CodecCapabilities.h
@@ -19,6 +19,7 @@
 #define CODEC_CAPABILITIES_H_
 
 #include <media/AudioCapabilities.h>
+#include <media/VideoCapabilities.h>
 #include <media/CodecCapabilitiesUtils.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <media/stagefright/foundation/AMessage.h>
@@ -52,6 +53,7 @@
     std::vector<ProfileLevel> mProfileLevels;
 
     std::shared_ptr<AudioCapabilities> mAudioCaps;
+    std::shared_ptr<VideoCapabilities> mVideoCaps;
 };
 
 }  // namespace android
diff --git a/media/libmedia/include/media/CodecCapabilitiesUtils.h b/media/libmedia/include/media/CodecCapabilitiesUtils.h
index 4ee8f04..7ca536a 100644
--- a/media/libmedia/include/media/CodecCapabilitiesUtils.h
+++ b/media/libmedia/include/media/CodecCapabilitiesUtils.h
@@ -117,6 +117,39 @@
         return Range(std::max(lower_, lower), std::min(upper_, upper));
     }
 
+    /**
+     * Returns the smallest range that includes this range and
+     * another range.
+     *
+     * E.g. if a < b < c < d, the
+     * extension of [a, c] and [b, d] ranges is [a, d].
+     * As the endpoints are object references, there is no guarantee
+     * which specific endpoint reference is used from the input ranges:
+     *
+     * E.g. if a == a' < b < c, the
+     * extension of [a, b] and [a', c] ranges could be either
+     * [a, c] or ['a, c], where ['a, c] could be either the exact
+     * input range, or a newly created range with the same endpoints.
+     *
+     * @param range a non-null Range<T> reference
+     * @return the extension of this range and the other range.
+     */
+    Range<T> extend(Range<T> range) {
+        return Range<T>(std::min(lower_, range.lower_), std::max(upper_, range.upper_));
+    }
+
+    Range<T> align(T align) {
+        return this->intersect(
+                divUp(lower_, align) * align, (upper_ / align) * align);
+    }
+
+    Range<T> factor(T factor) {
+        if (factor == 1) {
+            return *this;
+        }
+        return Range(divUp(this->lower(), factor), this->upper() / factor);
+    }
+
     // parse a string into a range
     static std::optional<Range<T>> Parse(const std::string &str) {
         if (str.empty()) {
@@ -148,6 +181,10 @@
         return std::make_optional<Range<T>>((T)lower, (T)upper);
     }
 
+    static Range<T> RangeFor(double v) {
+        return Range((T)v, (T)ceil(v));
+    }
+
 private:
     T lower_;
     T upper_;
@@ -160,7 +197,7 @@
 // found profile/level for which we don't have capability estimates
 constexpr int ERROR_CAPABILITIES_UNSUPPORTED    = (1 << 1);
 // have not found any profile/level for which we don't have capability estimate
-// constexpr int ERROR_NONE_SUPPORTED = (1 << 2);
+constexpr int ERROR_CAPABILITIES_NONE_SUPPORTED = (1 << 2);
 
 /**
  * Sorts distinct (non-intersecting) range array in ascending order.
@@ -211,6 +248,465 @@
     return result;
 }
 
+/**
+ * Immutable class for describing width and height dimensions in pixels.
+ */
+struct VideoSize {
+    /**
+     * Create a new immutable VideoSize instance.
+     *
+     * @param width The width of the size, in pixels
+     * @param height The height of the size, in pixels
+     */
+    VideoSize(int32_t width, int32_t height);
+
+    // default constructor
+    VideoSize();
+
+    /**
+     * Get the width of the size (in pixels).
+     * @return width
+     */
+    int32_t getWidth() const;
+
+    /**
+     * Get the height of the size (in pixels).
+     * @return height
+     */
+    int32_t getHeight() const;
+
+    /**
+     * Check if this size is equal to another size.
+     *
+     * Two sizes are equal if and only if both their widths and heights are
+     * equal.
+     *
+     * A size object is never equal to any other type of object.
+     *
+     * @return true if the objects were equal, false otherwise
+     */
+    bool equals(VideoSize other) const;
+
+    bool empty() const;
+
+    std::string toString() const;
+
+    /**
+     * Parses the specified string as a size value.
+     *
+     * The ASCII characters {@code \}{@code u002a} ('*') and
+     * {@code \}{@code u0078} ('x') are recognized as separators between
+     * the width and height.
+     *
+     * For any {@code VideoSize s}: {@code VideoSize::ParseSize(s.toString()).equals(s)}.
+     * However, the method also handles sizes expressed in the
+     * following forms:
+     *
+     * "<i>width</i>{@code x}<i>height</i>" or
+     * "<i>width</i>{@code *}<i>height</i>" {@code => new VideoSize(width, height)},
+     * where <i>width</i> and <i>height</i> are string integers potentially
+     * containing a sign, such as "-10", "+7" or "5".
+     *
+     * <pre>{@code
+     * VideoSize::ParseSize("3*+6").equals(new VideoSize(3, 6)) == true
+     * VideoSize::ParseSize("-3x-6").equals(new VideoSize(-3, -6)) == true
+     * VideoSize::ParseSize("4 by 3") => throws NumberFormatException
+     * }</pre>
+     *
+     * @param string the string representation of a size value.
+     * @return the size value represented by {@code string}.
+     */
+    static std::optional<VideoSize> ParseSize(std::string str);
+
+    static std::optional<std::pair<VideoSize, VideoSize>> ParseSizeRange(const std::string str);
+
+    static Range<int32_t> GetAllowedDimensionRange();
+
+private:
+    int32_t mWidth;
+    int32_t mHeight;
+};
+
+// This is used for the std::map<VideoSize> in VideoCapabilities
+struct VideoSizeCompare {
+    bool operator() (const VideoSize& lhs, const VideoSize& rhs) const {
+        if (lhs.getWidth() == rhs.getWidth()) {
+            return lhs.getHeight() < rhs.getHeight();
+        } else {
+            return lhs.getWidth() < rhs.getWidth();
+        }
+    }
+};
+
+/**
+ * An immutable data type representation a rational number.
+ *
+ * Contains a pair of ints representing the numerator and denominator of a
+ * Rational number.
+ */
+struct Rational {
+    /**
+     * <p>Create a {@code Rational} with a given numerator and denominator.</p>
+     *
+     * <p>The signs of the numerator and the denominator may be flipped such that the denominator
+     * is always positive. Both the numerator and denominator will be converted to their reduced
+     * forms (see {@link #equals} for more details).</p>
+     *
+     * <p>For example,
+     * <ul>
+     * <li>a rational of {@code 2/4} will be reduced to {@code 1/2}.
+     * <li>a rational of {@code 1/-1} will be flipped to {@code -1/1}
+     * <li>a rational of {@code 5/0} will be reduced to {@code 1/0}
+     * <li>a rational of {@code 0/5} will be reduced to {@code 0/1}
+     * </ul>
+     * </p>
+     *
+     * @param numerator the numerator of the rational
+     * @param denominator the denominator of the rational
+     *
+     * @see #equals
+     */
+    Rational(int32_t numerator, int32_t denominator) {
+        if (denominator < 0) {
+            numerator = -numerator;
+            denominator = -denominator;
+        }
+
+        // Convert to reduced form
+        if (denominator == 0 && numerator > 0) {
+            mNumerator = 1; // +Inf
+            mDenominator = 0;
+        } else if (denominator == 0 && numerator < 0) {
+            mNumerator = -1; // -Inf
+            mDenominator = 0;
+        } else if (denominator == 0 && numerator == 0) {
+            mNumerator = 0; // NaN
+            mDenominator = 0;
+        } else if (numerator == 0) {
+            mNumerator = 0;
+            mDenominator = 1;
+        } else {
+            int gcd = std::gcd(numerator, denominator);
+
+            mNumerator = numerator / gcd;
+            mDenominator = denominator / gcd;
+        }
+    }
+
+    // default constructor;
+    Rational() {
+        Rational(0, 0);
+    }
+
+    /**
+     * Gets the numerator of the rational.
+     *
+     * <p>The numerator will always return {@code 1} if this rational represents
+     * infinity (that is, the denominator is {@code 0}).</p>
+     */
+    int32_t getNumerator() const {
+        return mNumerator;
+    }
+
+    /**
+     * Gets the denominator of the rational
+     *
+     * <p>The denominator may return {@code 0}, in which case the rational may represent
+     * positive infinity (if the numerator was positive), negative infinity (if the numerator
+     * was negative), or {@code NaN} (if the numerator was {@code 0}).</p>
+     *
+     * <p>The denominator will always return {@code 1} if the numerator is {@code 0}.
+     */
+    int32_t getDenominator() const {
+        return mDenominator;
+    }
+
+    /**
+     * Indicates whether this rational is a <em>Not-a-Number (NaN)</em> value.
+     *
+     * <p>A {@code NaN} value occurs when both the numerator and the denominator are {@code 0}.</p>
+     *
+     * @return {@code true} if this rational is a <em>Not-a-Number (NaN)</em> value;
+     *         {@code false} if this is a (potentially infinite) number value
+     */
+    bool isNaN() const {
+        return mDenominator == 0 && mNumerator == 0;
+    }
+
+    /**
+     * Indicates whether this rational represents an infinite value.
+     *
+     * <p>An infinite value occurs when the denominator is {@code 0} (but the numerator is not).</p>
+     *
+     * @return {@code true} if this rational is a (positive or negative) infinite value;
+     *         {@code false} if this is a finite number value (or {@code NaN})
+     */
+    bool isInfinite() const {
+        return mNumerator != 0 && mDenominator == 0;
+    }
+
+    /**
+     * Indicates whether this rational represents a finite value.
+     *
+     * <p>A finite value occurs when the denominator is not {@code 0}; in other words
+     * the rational is neither infinity or {@code NaN}.</p>
+     *
+     * @return {@code true} if this rational is a (positive or negative) infinite value;
+     *         {@code false} if this is a finite number value (or {@code NaN})
+     */
+    bool isFinite() const {
+        return mDenominator != 0;
+    }
+
+    /**
+     * Indicates whether this rational represents a zero value.
+     *
+     * <p>A zero value is a {@link #isFinite finite} rational with a numerator of {@code 0}.</p>
+     *
+     * @return {@code true} if this rational is finite zero value;
+     *         {@code false} otherwise
+     */
+    bool isZero() const {
+        return isFinite() && mNumerator == 0;
+    }
+
+    /**
+     * Return a string representation of this rational, e.g. {@code "1/2"}.
+     *
+     * <p>The following rules of conversion apply:
+     * <ul>
+     * <li>{@code NaN} values will return {@code "NaN"}
+     * <li>Positive infinity values will return {@code "Infinity"}
+     * <li>Negative infinity values will return {@code "-Infinity"}
+     * <li>All other values will return {@code "numerator/denominator"} where {@code numerator}
+     * and {@code denominator} are substituted with the appropriate numerator and denominator
+     * values.
+     * </ul></p>
+     */
+    std::string toString() const {
+        if (isNaN()) {
+            return "NaN";
+        } else if (isPosInf()) {
+            return "Infinity";
+        } else if (isNegInf()) {
+            return "-Infinity";
+        } else {
+            return std::to_string(mNumerator) + "/" + std::to_string(mDenominator);
+        }
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code double}.
+     *
+     * <p>The {@code double} is calculated by converting both the numerator and denominator
+     * to a {@code double}; then returning the result of dividing the numerator by the
+     * denominator.</p>
+     *
+     * @return the divided value of the numerator and denominator as a {@code double}.
+     */
+    double asDouble() const {
+        double num = mNumerator;
+        double den = mDenominator;
+
+        return num / den;
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code float}.
+     *
+     * <p>The {@code float} is calculated by converting both the numerator and denominator
+     * to a {@code float}; then returning the result of dividing the numerator by the
+     * denominator.</p>
+     *
+     * @return the divided value of the numerator and denominator as a {@code float}.
+     */
+    float asfloat() const {
+        float num = mNumerator;
+        float den = mDenominator;
+
+        return num / den;
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code int}.
+     *
+     * <p>{@link #isInfinite Finite} rationals are converted to an {@code int} value
+     * by dividing the numerator by the denominator; conversion for non-finite values happens
+     * identically to casting a floating point value to an {@code int}, in particular:
+     *
+     * @return the divided value of the numerator and denominator as a {@code int}.
+     */
+    int32_t asInt32() const {
+        // Mimic float to int conversion rules from JLS 5.1.3
+
+        if (isPosInf()) {
+            return INT32_MAX;
+        } else if (isNegInf()) {
+            return INT32_MIN;
+        } else if (isNaN()) {
+            return 0;
+        } else { // finite
+            return mNumerator / mDenominator;
+        }
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code long}.
+     *
+     * <p>{@link #isInfinite Finite} rationals are converted to an {@code long} value
+     * by dividing the numerator by the denominator; conversion for non-finite values happens
+     * identically to casting a floating point value to a {@code long}, in particular:
+     *
+     * @return the divided value of the numerator and denominator as a {@code long}.
+     */
+    int64_t asInt64() const {
+        // Mimic float to long conversion rules from JLS 5.1.3
+
+        if (isPosInf()) {
+            return INT64_MAX;
+        } else if (isNegInf()) {
+            return INT64_MIN;
+        } else if (isNaN()) {
+            return 0;
+        } else { // finite
+            return mNumerator / mDenominator;
+        }
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code short}.
+     *
+     * <p>{@link #isInfinite Finite} rationals are converted to a {@code short} value
+     * identically to {@link #intValue}; the {@code int} result is then truncated to a
+     * {@code short} before returning the value.</p>
+     *
+     * @return the divided value of the numerator and denominator as a {@code short}.
+     */
+    int16_t asInt16() const {
+        return (int16_t) asInt32();
+    }
+
+    /**
+     * Compare this rational to the specified rational to determine their natural order.
+     *
+     * Nan is considered to be equal to itself and greater than all other
+     * Rational values. Otherwise, if the objects are not equal, then
+     * the following rules apply:
+     *
+     * Positive infinity is greater than any other finite number (or negative infinity)
+     * Negative infinity is less than any other finite number (or positive infinity)
+     * The finite number represented by this rational is checked numerically
+     * against the other finite number by converting both rationals to a common denominator multiple
+     * and comparing their numerators.
+     *
+     * @param another the rational to be compared
+     *
+     * @return a negative integer, zero, or a positive integer as this object is less than,
+     *         equal to, or greater than the specified rational.
+     */
+    // bool operator> (const Rational& another) {
+    int compareTo(Rational another) const {
+        if (equals(another)) {
+            return 0;
+        } else if (isNaN()) { // NaN is greater than the other non-NaN value
+            return 1;
+        } else if (another.isNaN()) { // the other NaN is greater than this non-NaN value
+            return -1;
+        } else if (isPosInf() || another.isNegInf()) {
+            return 1; // positive infinity is greater than any non-NaN/non-posInf value
+        } else if (isNegInf() || another.isPosInf()) {
+            return -1; // negative infinity is less than any non-NaN/non-negInf value
+        }
+
+        // else both this and another are finite numbers
+
+        // make the denominators the same, then compare numerators. int64_t to avoid overflow
+        int64_t thisNumerator = ((int64_t)mNumerator) * another.mDenominator;
+        int64_t otherNumerator = ((int64_t)another.mNumerator) * mDenominator;
+
+        // avoid underflow from subtraction by doing comparisons
+        if (thisNumerator < otherNumerator) {
+            return -1;
+        } else if (thisNumerator > otherNumerator) {
+            return 1;
+        } else {
+            // This should be covered by #equals, but have this code path just in case
+            return 0;
+        }
+    }
+
+    bool operator > (const Rational& another) const {
+        return compareTo(another) > 0;
+    }
+
+    bool operator >= (const Rational& another) const {
+        return compareTo(another) >= 0;
+    }
+
+    bool operator < (const Rational& another) const {
+        return compareTo(another) < 0;
+    }
+
+    bool operator <= (const Rational& another) const {
+        return compareTo(another) <= 0;
+    }
+
+    bool operator == (const Rational& another) const {
+        return equals(another);
+    }
+
+    static std::optional<Range<Rational>> ParseRange(const std::string str);
+
+    static Range<Rational> ScaleRange(Range<Rational> range, int32_t num, int32_t den);
+
+private:
+    int32_t mNumerator;
+    int32_t mDenominator;
+
+    bool isPosInf() const {
+        return mDenominator == 0 && mNumerator > 0;
+    }
+
+    bool isNegInf() const {
+        return mDenominator == 0 && mNumerator < 0;
+    }
+
+    bool equals(Rational other) const {
+        return (mNumerator == other.mNumerator && mDenominator == other.mDenominator);
+    }
+
+    Rational scale(int32_t num, int32_t den);
+
+    /**
+     * Parses the specified string as a rational value.
+     * The ASCII characters {@code \}{@code u003a} (':') and
+     * {@code \}{@code u002f} ('/') are recognized as separators between
+     * the numerator and denominator.
+     *
+     * For any {@code Rational r}: {@code Rational::parseRational(r.toString()).equals(r)}.
+     * However, the method also handles rational numbers expressed in the
+     * following forms:
+     *
+     * "<i>num</i>{@code /}<i>den</i>" or
+     * "<i>num</i>{@code :}<i>den</i>" {@code => new Rational(num, den);},
+     * where <i>num</i> and <i>den</i> are string integers potentially
+     * containing a sign, such as "-10", "+7" or "5".
+     *
+     * Rational::Parse("3:+6").equals(new Rational(1, 2)) == true
+     * Rational::Parse("-3/-6").equals(new Rational(1, 2)) == true
+     * Rational::Parse("4.56") => return std::nullopt
+     *
+     * @param str the string representation of a rational value.
+     * @return the rational value wrapped by std::optional represented by str.
+     */
+    static std::optional<Rational> Parse(std::string str);
+};
+
+static const Rational NaN = Rational(0, 0);
+static const Rational POSITIVE_INFINITY = Rational(1, 0);
+static const Rational NEGATIVE_INFINITY = Rational(-1, 0);
+static const Rational ZERO = Rational(0, 1);
+
 }  // namespace android
 
 #endif  // CODEC_CAPABILITIES__UTILS_H_
\ No newline at end of file
diff --git a/media/libmedia/include/media/VideoCapabilities.h b/media/libmedia/include/media/VideoCapabilities.h
new file mode 100644
index 0000000..5671375
--- /dev/null
+++ b/media/libmedia/include/media/VideoCapabilities.h
@@ -0,0 +1,457 @@
+/*
+ * Copyright 2024, 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 VIDEO_CAPABILITIES_H_
+
+#define VIDEO_CAPABILITIES_H_
+
+#include <media/CodecCapabilitiesUtils.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+struct VideoCapabilities {
+    struct PerformancePoint {
+        /**
+         * Maximum number of macroblocks in the frame.
+         *
+         * Video frames are conceptually divided into 16-by-16 pixel blocks called macroblocks.
+         * Most coding standards operate on these 16-by-16 pixel blocks; thus, codec performance
+         * is characterized using such blocks.
+         *
+         * Test API
+         */
+        int32_t getMaxMacroBlocks() const;
+
+        /**
+         * Return the width.
+         *
+         * For internal use only.
+         */
+        int32_t getWidth() const;
+
+        /**
+         * Return the height.
+         *
+         * For internal use only.
+         */
+        int32_t getHeight() const;
+
+        /**
+         * Maximum frame rate in frames per second.
+         *
+         * Test API
+         */
+        int32_t getMaxFrameRate() const;
+
+        /**
+         * Maximum number of macroblocks processed per second.
+         *
+         * Test API
+         */
+        int64_t getMaxMacroBlockRate() const;
+
+        /**
+         * Return the block size.
+         *
+         * For internal use only.
+         */
+        VideoSize getBlockSize() const;
+
+        /**
+         * convert to a debug string
+         *
+         * Be careful about the serializable compatibility across API revisions.
+         */
+        std::string toString() const;
+
+        /**
+         * Create a detailed performance point with custom max frame rate and macroblock size.
+         *
+         * @param width  frame width in pixels
+         * @param height frame height in pixels
+         * @param frameRate frames per second for frame width and height
+         * @param maxFrameRate maximum frames per second for any frame size
+         * @param blockSize block size for codec implementation. Must be powers of two in both
+         *        width and height.
+         *
+         * Test API
+         */
+        PerformancePoint(int32_t width, int32_t height, int32_t frameRate, int32_t maxFrameRate,
+                VideoSize blockSize);
+
+        /**
+         * Create a detailed performance point with custom max frame rate and macroblock size.
+         *
+         * @param width  frame width in pixels
+         * @param height frame height in pixels
+         * @param maxFrameRate maximum frames per second for any frame size
+         * @param maxMacroBlockRate maximum number of macroblocks processed per second.
+         * @param blockSize block size for codec implementation. Must be powers of two in both
+         *        width and height.
+         *
+         * Test API
+         */
+        PerformancePoint(VideoSize blockSize, int32_t width, int32_t height, int maxFrameRate,
+                int64_t maxMacroBlockRate);
+
+        /**
+         * Convert a performance point to a larger blocksize.
+         *
+         * @param pp performance point. NonNull
+         * @param blockSize block size for codec implementation. NonNull.
+         *
+         * Test API
+         */
+        PerformancePoint(const PerformancePoint &pp, VideoSize newBlockSize);
+
+        /**
+         * Create a performance point for a given frame size and frame rate.
+         *
+         * @param width width of the frame in pixels
+         * @param height height of the frame in pixels
+         * @param frameRate frame rate in frames per second
+         */
+        PerformancePoint(int32_t width, int32_t height, int32_t frameRate);
+
+        /**
+         * Checks whether the performance point covers a media format.
+         *
+         * @param format Stream format considered
+         *
+         * @return {@code true} if the performance point covers the format.
+         */
+        bool covers(const sp<AMessage> &format) const;
+
+        /**
+         * Checks whether the performance point covers another performance point. Use this
+         * method to determine if a performance point advertised by a codec covers the
+         * performance point required. This method can also be used for loose ordering as this
+         * method is transitive.
+         *
+         * @param other other performance point considered
+         *
+         * @return {@code true} if the performance point covers the other.
+         */
+        bool covers(const PerformancePoint &other) const;
+
+        /**
+         * Check if two PerformancePoint instances are equal.
+         *
+         * @param other other PerformancePoint instance for comparison.
+         *
+         * @return true if two PerformancePoint are equal.
+         */
+        bool equals(const PerformancePoint &other) const;
+
+    private:
+        VideoSize mBlockSize; // codec block size in macroblocks
+        int32_t mWidth; // width in macroblocks
+        int32_t mHeight; // height in macroblocks
+        int32_t mMaxFrameRate; // max frames per second
+        int64_t mMaxMacroBlockRate; // max macro block rate
+
+        void init(int32_t width, int32_t height, int32_t frameRate, int32_t maxFrameRate,
+                VideoSize blockSize);
+
+        /** Saturates a 64 bit integer value to a 32 bit integer */
+        int32_t saturateInt64ToInt32(int64_t value) const;
+
+        /** This method may overflow */
+        int32_t align(int32_t value, int32_t alignment) const;
+
+        /** @return NonNull */
+        VideoSize getCommonBlockSize(const PerformancePoint &other) const;
+    };
+
+    /**
+     * Find the equivalent VP9 profile level.
+     *
+     * Not a public API to developers.
+     */
+    static int32_t EquivalentVP9Level(const sp<AMessage> &format);
+
+    /**
+     * Returns the range of supported bitrates in bits/second.
+     */
+    const Range<int32_t>& getBitrateRange() const;
+
+    /**
+     * Returns the range of supported video widths.
+     * 32-bit processes will not support resolutions larger than 4096x4096 due to
+     * the limited address space.
+     */
+    const Range<int32_t>& getSupportedWidths() const;
+
+    /**
+     * Returns the range of supported video heights.
+     * 32-bit processes will not support resolutions larger than 4096x4096 due to
+     * the limited address space.
+     */
+    const Range<int32_t>& getSupportedHeights() const;
+
+    /**
+     * Returns the alignment requirement for video width (in pixels).
+     *
+     * This is a power-of-2 value that video width must be a
+     * multiple of.
+     */
+    int32_t getWidthAlignment() const;
+
+    /**
+     * Returns the alignment requirement for video height (in pixels).
+     *
+     * This is a power-of-2 value that video height must be a
+     * multiple of.
+     */
+    int32_t getHeightAlignment() const;
+
+    /**
+     * Return the upper limit on the smaller dimension of width or height.
+     *
+     * Some codecs have a limit on the smaller dimension, whether it be
+     * the width or the height.  E.g. a codec may only be able to handle
+     * up to 1920x1080 both in landscape and portrait mode (1080x1920).
+     * In this case the maximum width and height are both 1920, but the
+     * smaller dimension limit will be 1080. For other codecs, this is
+     * {@code Math.min(getSupportedWidths().getUpper(),
+     * getSupportedHeights().getUpper())}.
+     */
+    int32_t getSmallerDimensionUpperLimit() const;
+
+    /**
+     * Returns the range of supported frame rates.
+     *
+     * This is not a performance indicator.  Rather, it expresses the
+     * limits specified in the coding standard, based on the complexities
+     * of encoding material for later playback at a certain frame rate,
+     * or the decoding of such material in non-realtime.
+     */
+    const Range<int32_t>& getSupportedFrameRates() const;
+
+    /**
+     * Returns the range of supported video widths for a video height.
+     * @param height the height of the video
+     */
+    std::optional<Range<int32_t>> getSupportedWidthsFor(int32_t height) const;
+
+    /**
+     * Returns the range of supported video heights for a video width
+     * @param width the width of the video
+     */
+    std::optional<Range<int32_t>> getSupportedHeightsFor(int32_t width) const;
+
+    /**
+     * Returns the range of supported video frame rates for a video size.
+     *
+     * This is not a performance indicator.  Rather, it expresses the limits specified in
+     * the coding standard, based on the complexities of encoding material of a given
+     * size for later playback at a certain frame rate, or the decoding of such material
+     * in non-realtime.
+
+     * @param width the width of the video
+     * @param height the height of the video
+     */
+    std::optional<Range<double>> getSupportedFrameRatesFor(int32_t width, int32_t height) const;
+
+    /**
+     * Returns the range of achievable video frame rates for a video size.
+     * May return {@code null}, if the codec did not publish any measurement
+     * data.
+     * <p>
+     * This is a performance estimate provided by the device manufacturer based on statistical
+     * sampling of full-speed decoding and encoding measurements in various configurations
+     * of common video sizes supported by the codec. As such it should only be used to
+     * compare individual codecs on the device. The value is not suitable for comparing
+     * different devices or even different android releases for the same device.
+     * <p>
+     * <em>On {@link android.os.Build.VERSION_CODES#M} release</em> the returned range
+     * corresponds to the fastest frame rates achieved in the tested configurations. As
+     * such, it should not be used to gauge guaranteed or even average codec performance
+     * on the device.
+     * <p>
+     * <em>On {@link android.os.Build.VERSION_CODES#N} release</em> the returned range
+     * corresponds closer to sustained performance <em>in tested configurations</em>.
+     * One can expect to achieve sustained performance higher than the lower limit more than
+     * 50% of the time, and higher than half of the lower limit at least 90% of the time
+     * <em>in tested configurations</em>.
+     * Conversely, one can expect performance lower than twice the upper limit at least
+     * 90% of the time.
+     * <p class=note>
+     * Tested configurations use a single active codec. For use cases where multiple
+     * codecs are active, applications can expect lower and in most cases significantly lower
+     * performance.
+     * <p class=note>
+     * The returned range value is interpolated from the nearest frame size(s) tested.
+     * Codec performance is severely impacted by other activity on the device as well
+     * as environmental factors (such as battery level, temperature or power source), and can
+     * vary significantly even in a steady environment.
+     * <p class=note>
+     * Use this method in cases where only codec performance matters, e.g. to evaluate if
+     * a codec has any chance of meeting a performance target. Codecs are listed
+     * in {@link MediaCodecList} in the preferred order as defined by the device
+     * manufacturer. As such, applications should use the first suitable codec in the
+     * list to achieve the best balance between power use and performance.
+     *
+     * @param width the width of the video
+     * @param height the height of the video
+     */
+    std::optional<Range<double>> getAchievableFrameRatesFor(int32_t width, int32_t height) const;
+
+    /**
+     * Returns the supported performance points. May return {@code null} if the codec did not
+     * publish any performance point information (e.g. the vendor codecs have not been updated
+     * to the latest android release). May return an empty list if the codec published that
+     * if does not guarantee any performance points.
+     * <p>
+     * This is a performance guarantee provided by the device manufacturer for hardware codecs
+     * based on hardware capabilities of the device.
+     * <p>
+     * The returned list is sorted first by decreasing number of pixels, then by decreasing
+     * width, and finally by decreasing frame rate.
+     * Performance points assume a single active codec. For use cases where multiple
+     * codecs are active, should use that highest pixel count, and add the frame rates of
+     * each individual codec.
+     * <p class=note>
+     * 32-bit processes will not support resolutions larger than 4096x4096 due to
+     * the limited address space, but performance points will be presented as is.
+     * In other words, even though a component publishes a performance point for
+     * a resolution higher than 4096x4096, it does not mean that the resolution is supported
+     * for 32-bit processes.
+     */
+    const std::vector<PerformancePoint>& getSupportedPerformancePoints() const;
+
+    /**
+     * Returns whether a given video size ({@code width} and
+     * {@code height}) and {@code frameRate} combination is supported.
+     */
+    bool areSizeAndRateSupported(int32_t width, int32_t height, double frameRate) const;
+
+    /**
+     * Returns whether a given video size ({@code width} and
+     * {@code height}) is supported.
+     */
+    bool isSizeSupported(int32_t width, int32_t height) const;
+
+    /**
+     * Returns if a media format is supported.
+     *
+     * Not exposed to public
+     */
+    bool supportsFormat(const sp<AMessage> &format) const;
+
+    /**
+     * Create VideoCapabilities.
+     */
+    static std::shared_ptr<VideoCapabilities> Create(std::string mediaType,
+            std::vector<ProfileLevel> profLevs, const sp<AMessage> &format);
+
+    /**
+     * Get the block size.
+     *
+     * Not a public API to developers
+     */
+    VideoSize getBlockSize() const;
+
+    /**
+     * Get the block count range.
+     *
+     * Not a public API to developers
+     */
+    const Range<int32_t>& getBlockCountRange() const;
+
+    /**
+     * Get the blocks per second range.
+     *
+     * Not a public API to developers
+     */
+    const Range<int64_t>& getBlocksPerSecondRange() const;
+
+    /**
+     * Get the aspect ratio range.
+     *
+     * Not a public API to developers
+     */
+    Range<Rational> getAspectRatioRange(bool blocks) const;
+
+private:
+    std::string mMediaType;
+    std::vector<ProfileLevel> mProfileLevels;
+    int mError;
+
+    Range<int32_t> mBitrateRange;
+    Range<int32_t> mHeightRange;
+    Range<int32_t> mWidthRange;
+    Range<int32_t> mBlockCountRange;
+    Range<int32_t> mHorizontalBlockRange;
+    Range<int32_t> mVerticalBlockRange;
+    Range<Rational> mAspectRatioRange;
+    Range<Rational> mBlockAspectRatioRange;
+    Range<int64_t> mBlocksPerSecondRange;
+    std::map<VideoSize, Range<int64_t>, VideoSizeCompare> mMeasuredFrameRates;
+    std::vector<PerformancePoint> mPerformancePoints;
+    Range<int32_t> mFrameRateRange;
+
+    int32_t mBlockWidth;
+    int32_t mBlockHeight;
+    int32_t mWidthAlignment;
+    int32_t mHeightAlignment;
+    int mSmallerDimensionUpperLimit;
+
+    bool mAllowMbOverride; // allow XML to override calculated limits
+
+    int32_t getBlockCount(int32_t width, int32_t height) const;
+    std::optional<VideoSize> findClosestSize(int32_t width, int32_t height) const;
+    std::optional<Range<double>> estimateFrameRatesFor(int32_t width, int32_t height) const;
+    bool supports(std::optional<int32_t> width, std::optional<int32_t> height,
+                std::optional<double> rate) const;
+    /* no public constructor */
+    VideoCapabilities() {}
+    void init(std::string mediaType, std::vector<ProfileLevel> profLevs,
+            const sp<AMessage> &format);
+    void initWithPlatformLimits();
+    std::vector<PerformancePoint> getPerformancePoints(const sp<AMessage> &format) const;
+    std::map<VideoSize, Range<int64_t>, VideoSizeCompare>
+            getMeasuredFrameRates(const sp<AMessage> &format) const;
+
+    static std::optional<std::pair<Range<int32_t>, Range<int32_t>>> ParseWidthHeightRanges(
+            const std::string &str);
+    void parseFromInfo(const sp<AMessage> &format);
+    void applyBlockLimits(int32_t blockWidth, int32_t blockHeight,
+            Range<int32_t> counts, Range<int64_t> rates, Range<Rational> ratios);
+    void applyAlignment(int32_t widthAlignment, int32_t heightAlignment);
+    void updateLimits();
+    void applyMacroBlockLimits(
+            int32_t maxHorizontalBlocks, int32_t maxVerticalBlocks,
+            int32_t maxBlocks, int64_t maxBlocksPerSecond,
+            int32_t blockWidth, int32_t blockHeight,
+            int32_t widthAlignment, int32_t heightAlignment);
+    void applyMacroBlockLimits(
+            int32_t minHorizontalBlocks, int32_t minVerticalBlocks,
+            int32_t maxHorizontalBlocks, int32_t maxVerticalBlocks,
+            int32_t maxBlocks, int64_t maxBlocksPerSecond,
+            int32_t blockWidth, int32_t blockHeight,
+            int32_t widthAlignment, int32_t heightAlignment);
+    void applyLevelLimits();
+
+    friend struct CodecCapabilities;
+};
+
+}  // namespace android
+
+#endif // VIDEO_CAPABILITIES_H_
\ No newline at end of file
diff --git a/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp b/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
index 83483d5..c1bd65a 100644
--- a/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
+++ b/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
@@ -148,3 +148,82 @@
     EXPECT_EQ(audioCaps->isSampleRateSupported(10000), true);
     EXPECT_EQ(audioCaps->isSampleRateSupported(193000), false);
 }
+
+class VideoCapsHevcTest : public testing::Test {
+protected:
+    VideoCapsHevcTest() {
+        std::string mediaType = MIMETYPE_VIDEO_HEVC;
+
+        sp<AMessage> details = new AMessage;
+        details->setString("alignment", "2x2");
+        details->setString("bitrate-range", "1-120000000");
+        details->setString("block-count-range", "1-32640");
+        details->setString("block-size", "16x16");
+        details->setString("blocks-per-second-range", "1-3916800");
+        details->setInt32("feature-adaptive-playback", 0);
+        details->setInt32("feature-can-swap-width-height", 1);
+        details->setString("max-concurrent-instances", "16");
+        details->setString("measured-frame-rate-1280x720-range", "547-553");
+        details->setString("measured-frame-rate-1920x1080-range", "569-572");
+        details->setString("measured-frame-rate-352x288-range", "1150-1250");
+        details->setString("measured-frame-rate-3840x2160-range", "159-159");
+        details->setString("measured-frame-rate-640x360-range", "528-529");
+        details->setString("measured-frame-rate-720x480-range", "546-548");
+        details->setString("performance-point-1280x720-range", "240");
+        details->setString("performance-point-3840x2160-range", "120");
+        details->setString("size-range", "64x64-3840x2176");
+
+        std::vector<ProfileLevel> profileLevel{
+            ProfileLevel(1, 8388608),
+            ProfileLevel(2, 8388608),
+            ProfileLevel(4096, 8388608),
+            ProfileLevel(8192, 8388608),
+        };
+
+        videoCaps = VideoCapabilities::Create(mediaType, profileLevel, details);
+    }
+
+    std::shared_ptr<VideoCapabilities> videoCaps;
+};
+
+TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_Alignment) {
+    int32_t widthAlignment = videoCaps->getWidthAlignment();
+    EXPECT_EQ(widthAlignment, 2);
+    int32_t heightAlignment = videoCaps->getHeightAlignment();
+    EXPECT_EQ(heightAlignment, 2);
+}
+
+TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_BitrateRange) {
+    const Range<int32_t>& bitrateRange = videoCaps->getBitrateRange();
+    EXPECT_EQ(bitrateRange.lower(), 1);
+    EXPECT_EQ(bitrateRange.upper(), 120000000);
+}
+
+TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_SupportedWidthsAndHeights) {
+    const Range<int32_t>& supportedWidths = videoCaps->getSupportedWidths();
+    EXPECT_EQ(supportedWidths.upper(), 3840);
+    const Range<int32_t>& supportedHeights = videoCaps->getSupportedHeights();
+    EXPECT_EQ(supportedHeights.upper(), 3840);
+}
+
+TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_SupportedFrameRates) {
+    const Range<int32_t>& supportedFrameRates = videoCaps->getSupportedFrameRates();
+    EXPECT_EQ(supportedFrameRates.lower(), 0);
+    EXPECT_EQ(supportedFrameRates.upper(), 960);
+
+    std::optional<Range<double>> supportedFR720p = videoCaps->getSupportedFrameRatesFor(1280, 720);
+    EXPECT_EQ(supportedFR720p.value().upper(), 960.0);
+    std::optional<Range<double>> supportedFR1080p
+            = videoCaps->getSupportedFrameRatesFor(1920, 1080);
+    EXPECT_EQ(supportedFR1080p.value().upper(), 480.0);
+    std::optional<Range<double>> supportedFR4k = videoCaps->getSupportedFrameRatesFor(3840, 2160);
+    EXPECT_EQ(std::round(supportedFR4k.value().upper()), 121);
+}
+
+TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_AchievableFrameRates) {
+    std::optional<Range<double>> achievableFR1080p
+            = videoCaps->getAchievableFrameRatesFor(1920, 1080);
+    ASSERT_NE(achievableFR1080p, std::nullopt) << "resolution not supported";
+    EXPECT_EQ(achievableFR1080p.value().lower(), 569);
+    EXPECT_EQ(achievableFR1080p.value().upper(), 572);
+}
diff --git a/media/module/foundation/include/media/stagefright/foundation/AUtils.h b/media/module/foundation/include/media/stagefright/foundation/AUtils.h
index 3b646dc..eb605a7 100644
--- a/media/module/foundation/include/media/stagefright/foundation/AUtils.h
+++ b/media/module/foundation/include/media/stagefright/foundation/AUtils.h
@@ -92,4 +92,13 @@
     return (err < (period / 2)) ? err : (period - err);
 }
 
+inline static bool IsPowerOfTwo(int32_t value) {
+    return (value & (value - 1)) == 0;
+}
+
+/** Checks if the value is a power of two and not zero. */
+inline static bool IsPowerOfTwoStrict(int32_t value) {
+    return value != 0 && (value & (value - 1)) == 0;
+}
+
 #endif  // A_UTILS_H_
