Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70250d35 authored by Ronghua Wu's avatar Ronghua Wu Committed by Android Git Automerger
Browse files

am 148c7c5c: Merge "media: Implement getAchievableFrameRatesFor with measured...

am 148c7c5c: Merge "media: Implement getAchievableFrameRatesFor with measured frame rate." into mnc-dev

* commit '148c7c5c':
  media: Implement getAchievableFrameRatesFor with measured frame rate.
parents a7e2ab6e 148c7c5c
Loading
Loading
Loading
Loading
+62 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.media;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
@@ -1003,6 +1005,7 @@ public final class MediaCodecInfo {
        private Range<Rational> mAspectRatioRange;
        private Range<Rational> mBlockAspectRatioRange;
        private Range<Long> mBlocksPerSecondRange;
        private Map<Size, Range<Long>> mMeasuredFrameRates;
        private Range<Integer> mFrameRateRange;

        private int mBlockWidth;
@@ -1195,6 +1198,28 @@ public final class MediaCodecInfo {
                            (double) mFrameRateRange.getUpper()));
        }

        @NonNull
        private Size findClosestSize(int width, int height) {
            int targetPixels = width * height;
            Size closestSize = null;
            int mimPixelsDiff = Integer.MAX_VALUE;
            for (Size size : mMeasuredFrameRates.keySet()) {
                int pixelsDiff = Math.abs(targetPixels - size.getWidth() * size.getHeight());
                if (pixelsDiff < mimPixelsDiff) {
                    mimPixelsDiff = pixelsDiff;
                    closestSize = size;
                }
            }
            return closestSize;
        }

        private Range<Double> estimateFrameRatesFor(int width, int height) {
            Size size = findClosestSize(width, height);
            Range<Long> range = mMeasuredFrameRates.get(size);
            Double ratio = (double)(width * height) / (size.getWidth() * size.getHeight());
            return Range.create(range.getLower() * ratio, range.getUpper() * ratio);
        }

        /**
         * Returns the range of achievable video frame rates for a video size.
         * May return {@code null}, if the codec did not publish any measurement
@@ -1208,14 +1233,20 @@ public final class MediaCodecInfo {
         *
         * @throws IllegalArgumentException if the video size is not supported.
         */
        @Nullable
        public Range<Double> getAchievableFrameRatesFor(int width, int height) {
            if (!supports(width, height, null)) {
                throw new IllegalArgumentException("unsupported size");
            }
            // TODO: get this data from the codec

            if (mMeasuredFrameRates == null || mMeasuredFrameRates.size() <= 0) {
                Log.w(TAG, "Codec did not publish any measurement data.");
                return null;
            }

            return estimateFrameRatesFor(width, height);
        }

        /**
         * Returns whether a given video size ({@code width} and
         * {@code height}) and {@code frameRate} combination is supported.
@@ -1346,6 +1377,34 @@ public final class MediaCodecInfo {
            mSmallerDimensionUpperLimit = SIZE_RANGE.getUpper();
        }

        private Map<Size, Range<Long>> getMeasuredFrameRates(Map<String, Object> map) {
            Map<Size, Range<Long>> ret = new HashMap<Size, Range<Long>>();
            final String prefix = "measured-frame-rate-";
            Set<String> keys = map.keySet();
            for (String key : keys) {
                // looking for: measured-frame-rate-WIDTHxHEIGHT-range
                if (!key.startsWith(prefix)) {
                    continue;
                }
                String subKey = key.substring(prefix.length());
                String[] temp = key.split("-");
                if (temp.length != 5) {
                    continue;
                }
                String sizeStr = temp[3];
                Size size = Utils.parseSize(sizeStr, null);
                if (size == null || size.getWidth() * size.getHeight() <= 0) {
                    continue;
                }
                Range<Long> range = Utils.parseLongRange(map.get(key), null);
                if (range == null || range.getLower() < 0 || range.getUpper() < 0) {
                    continue;
                }
                ret.put(size, range);
            }
            return ret;
        }

        private void parseFromInfo(MediaFormat info) {
            final Map<String, Object> map = info.getMap();
            Size blockSize = new Size(mBlockWidth, mBlockHeight);
@@ -1360,6 +1419,7 @@ public final class MediaCodecInfo {
            counts = Utils.parseIntRange(map.get("block-count-range"), null);
            blockRates =
                Utils.parseLongRange(map.get("blocks-per-second-range"), null);
            mMeasuredFrameRates = getMeasuredFrameRates(map);
            {
                Object o = map.get("size-range");
                Pair<Size, Size> sizeRange = Utils.parseSizeRange(o);