diff --git a/api/current.txt b/api/current.txt
index 6fbb5ce..2ff971b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14526,7 +14526,6 @@
     method public abstract long getTimestamp();
     method public abstract int getWidth();
     method public void setCropRect(android.graphics.Rect);
-    field protected android.graphics.Rect mCropRect;
   }
 
   public static abstract class Image.Plane {
@@ -14658,7 +14657,6 @@
   }
 
   public static final class MediaCodec.CodecException extends java.lang.IllegalStateException {
-    ctor public MediaCodec.CodecException(int, int, java.lang.String);
     method public int getErrorCode();
     method public boolean isRecoverable();
     method public boolean isTransient();
@@ -14690,14 +14688,22 @@
     method public final boolean isEncoder();
   }
 
+  public static final class MediaCodecInfo.AudioCapabilities {
+    method public android.util.Range<java.lang.Integer> getBitrateRange();
+    method public int getMaxInputChannelCount();
+    method public android.util.Range<java.lang.Integer>[] getSupportedSampleRateRanges();
+    method public int[] getSupportedSampleRates();
+    method public boolean isSampleRateSupported(int);
+  }
+
   public static final class MediaCodecInfo.CodecCapabilities {
     ctor public MediaCodecInfo.CodecCapabilities();
-    method public static final android.media.MediaCodecInfo.CodecCapabilities CreateFromProfileLevel(java.lang.String, int, int);
-    method public final android.media.MediaCodecInfo.CodecCapabilities.AudioCapabilities getAudioCapabilities();
-    method public final android.media.MediaFormat getDefaultFormat();
-    method public final android.media.MediaCodecInfo.CodecCapabilities.EncoderCapabilities getEncoderCapabilities();
-    method public final java.lang.String getMime();
-    method public final android.media.MediaCodecInfo.CodecCapabilities.VideoCapabilities getVideoCapabilities();
+    method public static android.media.MediaCodecInfo.CodecCapabilities CreateFromProfileLevel(java.lang.String, int, int);
+    method public android.media.MediaCodecInfo.AudioCapabilities getAudioCapabilities();
+    method public android.media.MediaFormat getDefaultFormat();
+    method public android.media.MediaCodecInfo.EncoderCapabilities getEncoderCapabilities();
+    method public java.lang.String getMimeType();
+    method public android.media.MediaCodecInfo.VideoCapabilities getVideoCapabilities();
     method public final boolean isFeatureRequired(java.lang.String);
     method public final boolean isFeatureSupported(java.lang.String);
     method public final boolean isFormatSupported(android.media.MediaFormat);
@@ -14755,39 +14761,6 @@
     field public android.media.MediaCodecInfo.CodecProfileLevel[] profileLevels;
   }
 
-  public static final class MediaCodecInfo.CodecCapabilities.AudioCapabilities extends android.media.MediaCodecInfo.CodecCapabilities.BaseCapabilities {
-    method public final int getMaxInputChannelCount();
-    method public final android.util.Range<java.lang.Integer>[] getSupportedSampleRateRanges();
-    method public final int[] getSupportedSampleRates();
-    method public final boolean isSampleRateSupported(int);
-  }
-
-  public static class MediaCodecInfo.CodecCapabilities.BaseCapabilities {
-    method public final android.util.Range<java.lang.Integer> getBitrateRange();
-  }
-
-  public static final class MediaCodecInfo.CodecCapabilities.EncoderCapabilities {
-    method public final android.util.Range<java.lang.Integer> getComplexityRange();
-    method public final android.util.Range<java.lang.Integer> getQualityRange();
-    method public final boolean isBitrateModeSupported(int);
-    field public static final int BITRATE_MODE_CBR = 2; // 0x2
-    field public static final int BITRATE_MODE_CQ = 0; // 0x0
-    field public static final int BITRATE_MODE_VBR = 1; // 0x1
-  }
-
-  public static final class MediaCodecInfo.CodecCapabilities.VideoCapabilities extends android.media.MediaCodecInfo.CodecCapabilities.BaseCapabilities {
-    method public final boolean areSizeAndRateSupported(int, int, double);
-    method public final int getHeightAlignment();
-    method public final android.util.Range<java.lang.Integer> getSupportedFrameRates();
-    method public final android.util.Range<java.lang.Double> getSupportedFrameRatesFor(int, int);
-    method public final android.util.Range<java.lang.Integer> getSupportedHeights();
-    method public final android.util.Range<java.lang.Integer> getSupportedHeightsFor(int);
-    method public final android.util.Range<java.lang.Integer> getSupportedWidths();
-    method public final android.util.Range<java.lang.Integer> getSupportedWidthsFor(int);
-    method public final int getWidthAlignment();
-    method public final boolean isSizeSupported(int, int);
-  }
-
   public static final class MediaCodecInfo.CodecProfileLevel {
     ctor public MediaCodecInfo.CodecProfileLevel();
     field public static final int AACObjectELD = 39; // 0x27
@@ -14902,12 +14875,34 @@
     field public int profile;
   }
 
+  public static final class MediaCodecInfo.EncoderCapabilities {
+    method public android.util.Range<java.lang.Integer> getComplexityRange();
+    method public boolean isBitrateModeSupported(int);
+    field public static final int BITRATE_MODE_CBR = 2; // 0x2
+    field public static final int BITRATE_MODE_CQ = 0; // 0x0
+    field public static final int BITRATE_MODE_VBR = 1; // 0x1
+  }
+
+  public static final class MediaCodecInfo.VideoCapabilities {
+    method public boolean areSizeAndRateSupported(int, int, double);
+    method public android.util.Range<java.lang.Integer> getBitrateRange();
+    method public int getHeightAlignment();
+    method public android.util.Range<java.lang.Integer> getSupportedFrameRates();
+    method public android.util.Range<java.lang.Double> getSupportedFrameRatesFor(int, int);
+    method public android.util.Range<java.lang.Integer> getSupportedHeights();
+    method public android.util.Range<java.lang.Integer> getSupportedHeightsFor(int);
+    method public android.util.Range<java.lang.Integer> getSupportedWidths();
+    method public android.util.Range<java.lang.Integer> getSupportedWidthsFor(int);
+    method public int getWidthAlignment();
+    method public boolean isSizeSupported(int, int);
+  }
+
   public final class MediaCodecList {
     ctor public MediaCodecList(int);
     method public final java.lang.String findDecoderForFormat(android.media.MediaFormat);
     method public final java.lang.String findEncoderForFormat(android.media.MediaFormat);
-    method public static final int getCodecCount();
-    method public static final android.media.MediaCodecInfo getCodecInfoAt(int);
+    method public static final deprecated int getCodecCount();
+    method public static final deprecated android.media.MediaCodecInfo getCodecInfoAt(int);
     method public final android.media.MediaCodecInfo[] getCodecInfos();
     field public static final int ALL_CODECS = 1; // 0x1
     field public static final int REGULAR_CODECS = 0; // 0x0
@@ -15026,11 +15021,13 @@
     method public static final android.media.MediaFormat createSubtitleFormat(java.lang.String, java.lang.String);
     method public static final android.media.MediaFormat createVideoFormat(java.lang.String, int, int);
     method public final java.nio.ByteBuffer getByteBuffer(java.lang.String);
+    method public boolean getFeatureEnabled(java.lang.String);
     method public final float getFloat(java.lang.String);
     method public final int getInteger(java.lang.String);
     method public final long getLong(java.lang.String);
     method public final java.lang.String getString(java.lang.String);
     method public final void setByteBuffer(java.lang.String, java.nio.ByteBuffer);
+    method public void setFeatureEnabled(java.lang.String, boolean);
     method public final void setFloat(java.lang.String, float);
     method public final void setInteger(java.lang.String, int);
     method public final void setLong(java.lang.String, long);
@@ -15052,7 +15049,6 @@
     field public static final java.lang.String KEY_COLOR_FORMAT = "color-format";
     field public static final java.lang.String KEY_COMPLEXITY = "complexity";
     field public static final java.lang.String KEY_DURATION = "durationUs";
-    field public static final java.lang.String KEY_FEATURE_ = "feature-";
     field public static final java.lang.String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
     field public static final java.lang.String KEY_FRAME_RATE = "frame-rate";
     field public static final java.lang.String KEY_HEIGHT = "height";
@@ -15068,7 +15064,6 @@
     field public static final java.lang.String KEY_MIME = "mime";
     field public static final java.lang.String KEY_PROFILE = "profile";
     field public static final java.lang.String KEY_PUSH_BLANK_BUFFERS_ON_STOP = "push-blank-buffers-on-shutdown";
-    field public static final java.lang.String KEY_QUALITY = "quality";
     field public static final java.lang.String KEY_REPEAT_PREVIOUS_FRAME_AFTER = "repeat-previous-frame-after";
     field public static final java.lang.String KEY_SAMPLE_RATE = "sample-rate";
     field public static final java.lang.String KEY_TEMPORAL_LAYERING = "ts-schema";
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 2856edb..522e45d 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -123,7 +123,7 @@
      */
     public abstract long getTimestamp();
 
-    protected Rect mCropRect;
+    private Rect mCropRect;
 
     /**
      * Get the crop rectangle associated with this frame.
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 96e6ab9..032f07f 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -665,7 +665,7 @@
      * Thrown when an internal codec error occurs.
      */
     public final static class CodecException extends IllegalStateException {
-        public CodecException(int errorCode, int actionCode, String detailMessage) {
+        CodecException(int errorCode, int actionCode, String detailMessage) {
             super(detailMessage);
             mErrorCode = errorCode;
             mActionCode = actionCode;
@@ -1729,7 +1729,7 @@
             if (cropRect != null) {
                 cropRect.offset(-xOffset, -yOffset);
             }
-            mCropRect = cropRect;
+            setCropRect(cropRect);
 
             // save offsets and info
             mXOffset = xOffset;
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index acb2186..323a3e3 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -70,7 +70,7 @@
         mIsEncoder = isEncoder;
         mCaps = new HashMap<String, CodecCapabilities>();
         for (CodecCapabilities c: caps) {
-            mCaps.put(c.getMime(), c);
+            mCaps.put(c.getMimeType(), c);
         }
     }
 
@@ -98,6 +98,43 @@
         return types;
     }
 
+    private static int checkPowerOfTwo(int value, String message) {
+        if ((value & (value - 1)) != 0) {
+            throw new IllegalArgumentException(message);
+        }
+        return value;
+    }
+
+    private static class Feature {
+        public String mName;
+        public int mValue;
+        public boolean mDefault;
+        public Feature(String name, int value, boolean def) {
+            mName = name;
+            mValue = value;
+            mDefault = def;
+        }
+    }
+
+    // COMMON CONSTANTS
+    private static final Range<Integer> POSITIVE_INTEGERS =
+        Range.create(1, Integer.MAX_VALUE);
+    private static final Range<Long> POSITIVE_LONGS =
+        Range.create(1l, Long.MAX_VALUE);
+    private static final Range<Rational> POSITIVE_RATIONALS =
+        Range.create(new Rational(1, Integer.MAX_VALUE),
+                     new Rational(Integer.MAX_VALUE, 1));
+    private static final Range<Integer> SIZE_RANGE = Range.create(1, 32768);
+    private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960);
+
+    // found stuff that is not supported by framework (=> this should not happen)
+    private static final int ERROR_UNRECOGNIZED   = (1 << 0);
+    // found profile/level for which we don't have capability estimates
+    private static final int ERROR_UNSUPPORTED    = (1 << 1);
+    // have not found any profile/level for which we don't have capability estimate
+    private static final int ERROR_NONE_SUPPORTED = (1 << 2);
+
+
     /**
      * Encapsulates the capabilities of a given codec component.
      * For example, what profile/level combinations it supports and what colorspaces
@@ -222,17 +259,6 @@
             return checkFeature(name, mFlagsRequired);
         }
 
-        private static class Feature {
-            public String mName;
-            public int mValue;
-            public boolean mDefault;
-            public Feature(String name, int value, boolean def) {
-                mName = name;
-                mValue = value;
-                mDefault = def;
-            }
-        }
-
         private static final Feature[] decoderFeatures = {
             new Feature(FEATURE_AdaptivePlayback, (1 << 0), true),
             new Feature(FEATURE_SecurePlayback,   (1 << 1), false),
@@ -312,1311 +338,54 @@
             return true;
         }
 
-        // errors while reading profile levels
-        private int mError;
-        // found stuff that is not supported by framework (=> this should not happen)
-        private static final int ERROR_UNRECOGNIZED   = (1 << 0);
-        // found profile/level for which we don't have capability estimates
-        private static final int ERROR_UNSUPPORTED    = (1 << 1);
-        // have not found any profile/level for which we don't have capability estimate
-        private static final int ERROR_NONE_SUPPORTED = (1 << 2);
-
-
-        // UTILITY METHODS
-        private static final Range<Integer> POSITIVE_INTEGERS =
-            Range.create(1, Integer.MAX_VALUE);
-        private static final Range<Long> POSITIVE_LONGS =
-            Range.create(1l, Long.MAX_VALUE);
-        private static final Range<Rational> POSITIVE_RATIONALS =
-            Range.create(new Rational(1, Integer.MAX_VALUE),
-                         new Rational(Integer.MAX_VALUE, 1));
-        private static final Range<Integer> SIZE_RANGE = Range.create(1, 32768);
-        private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960);
+        // errors while reading profile levels - accessed from sister capabilities
+        int mError;
 
         private static final String TAG = "CodecCapabilities";
 
         // NEW-STYLE CAPABILITIES
+        private AudioCapabilities mAudioCaps;
+        private VideoCapabilities mVideoCaps;
+        private EncoderCapabilities mEncoderCaps;
+        private MediaFormat mDefaultFormat;
 
         /**
          * Returns a MediaFormat object with default values for configurations that have
          * defaults.
          */
-        public final MediaFormat getDefaultFormat() {
+        public MediaFormat getDefaultFormat() {
             return mDefaultFormat;
         }
-        private MediaFormat mDefaultFormat;
 
         /**
          * Returns the mime type for which this codec-capability object was created.
          */
-        public final String getMime() {
+        public String getMimeType() {
             return mMime;
         }
 
-        /**
-         * Returns the encoding capabilities or {@code null} if this is not an encoder.
-         */
-        public final EncoderCapabilities getEncoderCapabilities() {
-            return mEncoderCaps;
+        private boolean isAudio() {
+            return mAudioCaps != null;
         }
-        private EncoderCapabilities mEncoderCaps;
+
+        /**
+         * Returns the audio capabilities or {@code null} if this is not an audio codec.
+         */
+        public AudioCapabilities getAudioCapabilities() {
+            return mAudioCaps;
+        }
 
         private boolean isEncoder() {
             return mEncoderCaps != null;
         }
 
         /**
-         * A class that supports querying the encoding capabilities of a codec.
+         * Returns the encoding capabilities or {@code null} if this is not an encoder.
          */
-        public static final class EncoderCapabilities {
-            /**
-             * Returns the supported range of quality values.
-             */
-            public final Range<Integer> getQualityRange() {
-                return mQualityRange;
-            }
-
-            /**
-             * Returns the supported range of encoder complexity values.
-             * <p>
-             * Some codecs may support multiple complexity levels, where higher
-             * complexity values use more encoder tools (e.g. perform more
-             * intensive calculations) to improve the quality or the compression
-             * ratio.  Use a lower value to save power and/or time.
-             */
-            public final Range<Integer> getComplexityRange() {
-                return mComplexityRange;
-            }
-
-            /** Constant quality mode */
-            public static final int BITRATE_MODE_CQ = 0;
-            /** Variable bitrate mode */
-            public static final int BITRATE_MODE_VBR = 1;
-            /** Constant bitrate mode */
-            public static final int BITRATE_MODE_CBR = 2;
-
-            private static final Feature[] bitrates = new Feature[] {
-                new Feature("VBR", BITRATE_MODE_VBR, true),
-                new Feature("CBR", BITRATE_MODE_CBR, false),
-                new Feature("CQ",  BITRATE_MODE_CQ,  false)
-            };
-
-            private static int parseBitrateMode(String mode) {
-                for (Feature feat: bitrates) {
-                    if (feat.mName.equalsIgnoreCase(mode)) {
-                        return feat.mValue;
-                    }
-                }
-                return 0;
-            }
-
-            /**
-             * Query whether a bitrate mode is supported.
-             */
-            public final boolean isBitrateModeSupported(int mode) {
-                for (Feature feat: bitrates) {
-                    if (mode == feat.mValue) {
-                        return (mBitControl & (1 << mode)) != 0;
-                    }
-                }
-                return false;
-            }
-
-            private Range<Integer> mQualityRange;
-            private Range<Integer> mComplexityRange;
-            private CodecCapabilities mParent;
-
-            /* no public constructor */
-            private EncoderCapabilities() { }
-
-            /** @hide */
-            public static EncoderCapabilities create(
-                    MediaFormat info, CodecCapabilities parent) {
-                EncoderCapabilities caps = new EncoderCapabilities();
-                caps.init(info, parent);
-                return caps;
-            }
-
-            /** @hide */
-            public void init(MediaFormat info, CodecCapabilities parent) {
-                // no support for complexity or quality yet
-                mParent = parent;
-                mComplexityRange = Range.create(0, 0);
-                mQualityRange = Range.create(0, 0);
-                mBitControl = (1 << BITRATE_MODE_VBR);
-
-                applyLevelLimits();
-                parseFromInfo(info);
-            }
-
-            private void applyLevelLimits() {
-                String mime = mParent.getMime();
-                if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
-                    mComplexityRange = Range.create(0, 8);
-                    mBitControl = (1 << BITRATE_MODE_CQ);
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)
-                        || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)
-                        || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW)
-                        || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)
-                        || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) {
-                    mBitControl = (1 << BITRATE_MODE_CBR);
-                }
-            }
-
-            private int mBitControl;
-            private Integer mDefaultComplexity;
-            private Integer mDefaultQuality;
-            private String mQualityScale;
-
-            private void parseFromInfo(MediaFormat info) {
-                Map<String, Object> map = info.getMap();
-
-                if (info.containsKey("complexity-range")) {
-                    mComplexityRange = Utils
-                            .parseIntRange(info.getString("complexity-range"), mComplexityRange);
-                    // TODO should we limit this to level limits?
-                }
-                if (info.containsKey("quality-range")) {
-                    mQualityRange = Utils
-                            .parseIntRange(info.getString("quality-range"), mQualityRange);
-                }
-                if (info.containsKey("feature-bitrate-control")) {
-                    for (String mode: info.getString("feature-bitrate-control").split(",")) {
-                        mBitControl |= parseBitrateMode(mode);
-                    }
-                }
-
-                try {
-                    mDefaultComplexity = Integer.parseInt((String)map.get("complexity-default"));
-                } catch (NumberFormatException e) { }
-
-                try {
-                    mDefaultQuality = Integer.parseInt((String)map.get("quality-default"));
-                } catch (NumberFormatException e) { }
-
-                mQualityScale = (String)map.get("quality-scale");
-            }
-
-            private boolean supports(
-                    Integer complexity, Integer quality, Integer profile) {
-                boolean ok = true;
-                if (ok && complexity != null) {
-                    ok = mComplexityRange.contains(complexity);
-                }
-                if (ok && quality != null) {
-                    ok = mQualityRange.contains(quality);
-                }
-                if (ok && profile != null) {
-                    for (CodecProfileLevel pl: mParent.profileLevels) {
-                        if (pl.profile == profile) {
-                            profile = null;
-                            break;
-                        }
-                    }
-                    ok = profile == null;
-                }
-                return ok;
-            }
-
-            /** @hide */
-            public void setDefaultFormat(MediaFormat format) {
-                // don't list trivial quality/complexity as default for now
-                if (!mQualityRange.getUpper().equals(mQualityRange.getLower())
-                        && mDefaultQuality != null) {
-                    format.setInteger(MediaFormat.KEY_QUALITY, mDefaultQuality);
-                }
-                if (!mComplexityRange.getUpper().equals(mComplexityRange.getLower())
-                        && mDefaultComplexity != null) {
-                    format.setInteger(MediaFormat.KEY_COMPLEXITY, mDefaultComplexity);
-                }
-                // bitrates are listed in order of preference
-                for (Feature feat: bitrates) {
-                    if ((mBitControl & (1 << feat.mValue)) != 0) {
-                        format.setInteger(MediaFormat.KEY_BITRATE_MODE, feat.mValue);
-                        break;
-                    }
-                }
-            }
-
-            /** @hide */
-            public boolean supportsFormat(MediaFormat format) {
-                final Map<String, Object> map = format.getMap();
-                final String mime = mParent.getMime();
-
-                Integer mode = (Integer)map.get(MediaFormat.KEY_BITRATE_MODE);
-                if (mode != null && !isBitrateModeSupported(mode)) {
-                    return false;
-                }
-
-                Integer complexity = (Integer)map.get(MediaFormat.KEY_COMPLEXITY);
-                if (MediaFormat.MIMETYPE_AUDIO_FLAC.equalsIgnoreCase(mime)) {
-                    Integer flacComplexity =
-                        (Integer)map.get(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL);
-                    if (complexity == null) {
-                        complexity = flacComplexity;
-                    } else if (flacComplexity != null && complexity != flacComplexity) {
-                        throw new IllegalArgumentException(
-                                "conflicting values for complexity and " +
-                                "flac-compression-level");
-                    }
-                }
-
-                // other audio parameters
-                Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE);
-                if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mime)) {
-                    Integer aacProfile = (Integer)map.get(MediaFormat.KEY_AAC_PROFILE);
-                    if (profile == null) {
-                        profile = aacProfile;
-                    } else if (aacProfile != null && aacProfile != profile) {
-                        throw new IllegalArgumentException(
-                                "conflicting values for profile and aac-profile");
-                    }
-                }
-
-                Integer quality = (Integer)map.get(MediaFormat.KEY_QUALITY);
-
-                return supports(complexity, quality, profile);
-            }
-        };
-
-        /**
-         * A class that supports querying basic capabilities of a codec.
-         */
-        public static class BaseCapabilities {
-            /**
-             * Returns the range of supported bitrates in bits/second.
-             */
-            public final Range<Integer> getBitrateRange() {
-                return mBitrateRange;
-            }
-
-            /** @hide */
-            protected Range<Integer> mBitrateRange;
-
-            /** @hide */
-            protected CodecCapabilities mParent;
-
-            /** @hide */
-            protected BaseCapabilities() {
-            }
-
-            /** @hide */
-            protected void init(MediaFormat info, CodecCapabilities parent) {
-                mParent = parent;
-                mBitrateRange = Range.create(0, Integer.MAX_VALUE);
-            }
+        public EncoderCapabilities getEncoderCapabilities() {
+            return mEncoderCaps;
         }
 
-        /**
-         * A class that supports querying the video capabilities of a codec.
-         */
-        public static final class VideoCapabilities extends BaseCapabilities {
-            private static final String TAG = "VideoCapabilities";
-            private Range<Integer> mHeightRange;
-            private Range<Integer> mWidthRange;
-            private Range<Integer> mBlockCountRange;
-            private Range<Integer> mHorizontalBlockRange;
-            private Range<Integer> mVerticalBlockRange;
-            private Range<Rational> mAspectRatioRange;
-            private Range<Rational> mBlockAspectRatioRange;
-            private Range<Long> mBlocksPerSecondRange;
-            private Range<Integer> mFrameRateRange;
-
-            private int mBlockWidth;
-            private int mBlockHeight;
-            private int mWidthAlignment;
-            private int mHeightAlignment;
-            private int mSmallerDimensionUpperLimit;
-
-            /**
-             * Returns the range of supported video widths.
-             */
-            public final Range<Integer> getSupportedWidths() {
-                return mWidthRange;
-            }
-
-            /**
-             * Returns the range of supported video heights.
-             */
-            public final Range<Integer> getSupportedHeights() {
-                return mHeightRange;
-            }
-
-            /**
-             * Returns the alignment requirement for video width.
-             */
-            public final int getWidthAlignment() {
-                return mWidthAlignment;
-            }
-
-            /**
-             * Returns the alignment requirement for video height.
-             */
-            public final int getHeightAlignment() {
-                return mHeightAlignment;
-            }
-
-            /**
-             * Return the upper limit on the smaller dimension of width or height.
-             * <p></p>
-             * 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())}.
-             *
-             * @hide
-             */
-            public int getSmallerDimensionUpperLimit() {
-                return mSmallerDimensionUpperLimit;
-            }
-
-            /**
-             * Returns the range of supported frame rates.
-             * <p>
-             * 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.
-             */
-            public final Range<Integer> getSupportedFrameRates() {
-                return mFrameRateRange;
-            }
-
-            /**
-             * Returns the range of supported video widths for a video height.
-             * @param height the height of the video
-             */
-            public final Range<Integer> getSupportedWidthsFor(int height) {
-                try {
-                    Range<Integer> range = mWidthRange;
-                    if (!mHeightRange.contains(height)
-                            || (height % mHeightAlignment) != 0) {
-                        throw new IllegalArgumentException("unsupported height");
-                    }
-                    final int heightInBlocks = Utils.divUp(height, mBlockHeight);
-
-                    // constrain by block count and by block aspect ratio
-                    final int minWidthInBlocks = Math.max(
-                            Utils.divUp(mBlockCountRange.getLower(), heightInBlocks),
-                            (int)Math.ceil(mBlockAspectRatioRange.getLower().doubleValue()
-                                    * heightInBlocks));
-                    final int maxWidthInBlocks = Math.min(
-                            mBlockCountRange.getUpper() / heightInBlocks,
-                            (int)(mBlockAspectRatioRange.getUpper().doubleValue()
-                                    * 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(
-                            (int)Math.ceil(mAspectRatioRange.getLower().doubleValue()
-                                    * height),
-                            (int)(mAspectRatioRange.getUpper().doubleValue() * height));
-                    return range;
-                } catch (IllegalArgumentException e) {
-                    // should not be here
-                    Log.w(TAG, "could not get supported widths for " + height , e);
-                    throw new IllegalArgumentException("unsupported height");
-                }
-            }
-
-            /**
-             * Returns the range of supported video heights for a video width
-             * @param width the width of the video
-             */
-            public final Range<Integer> getSupportedHeightsFor(int width) {
-                try {
-                    Range<Integer> range = mHeightRange;
-                    if (!mWidthRange.contains(width)
-                            || (width % mWidthAlignment) != 0) {
-                        throw new IllegalArgumentException("unsupported width");
-                    }
-                    final int widthInBlocks = Utils.divUp(width, mBlockWidth);
-
-                    // constrain by block count and by block aspect ratio
-                    final int minHeightInBlocks = Math.max(
-                            Utils.divUp(mBlockCountRange.getLower(), widthInBlocks),
-                            (int)Math.ceil(widthInBlocks /
-                                    mBlockAspectRatioRange.getUpper().doubleValue()));
-                    final int maxHeightInBlocks = Math.min(
-                            mBlockCountRange.getUpper() / widthInBlocks,
-                            (int)(widthInBlocks /
-                                    mBlockAspectRatioRange.getLower().doubleValue()));
-                    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(
-                            (int)Math.ceil(width /
-                                    mAspectRatioRange.getUpper().doubleValue()),
-                            (int)(width / mAspectRatioRange.getLower().doubleValue()));
-                    return range;
-                } catch (IllegalArgumentException e) {
-                    // should not be here
-                    Log.w(TAG, "could not get supported heights for " + width , e);
-                    throw new IllegalArgumentException("unsupported width");
-                }
-            }
-
-            /**
-             * Returns the range of supported video frame rates for a video size.
-             * <p>
-             * 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
-             */
-            public final Range<Double> getSupportedFrameRatesFor(int width, int height) {
-                Range<Integer> range = mHeightRange;
-                if (!supports(width, height, null)) {
-                    throw new IllegalArgumentException("unsupported size");
-                }
-                final int blockCount =
-                    Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight);
-
-                return Range.create(
-                        Math.max(mBlocksPerSecondRange.getLower() / (double) blockCount,
-                                (double) mFrameRateRange.getLower()),
-                        Math.min(mBlocksPerSecondRange.getUpper() / (double) blockCount,
-                                (double) mFrameRateRange.getUpper()));
-            }
-
-            /**
-             * Returns whether a given video size ({@code width} and
-             * {@code height}) and {@code frameRate} combination is supported.
-             */
-            public final boolean areSizeAndRateSupported(
-                    int width, int height, double frameRate) {
-                return supports(width, height, frameRate);
-            }
-
-            /**
-             * Returns whether a given video size ({@code width} and
-             * {@code height}) is supported.
-             */
-            public final boolean isSizeSupported(int width, int height) {
-                return supports(width, height, null);
-            }
-
-            private final boolean supports(
-                    Integer width, Integer height, Double rate) {
-                boolean ok = true;
-
-                if (ok && width != null) {
-                    ok = mWidthRange.contains(width)
-                            && (width % mWidthAlignment == 0);
-                }
-                if (ok && height != null) {
-                    ok = mHeightRange.contains(height)
-                            && (height % mHeightAlignment == 0);
-                }
-                if (ok && rate != null) {
-                    ok = mFrameRateRange.contains(Utils.intRangeFor(rate));
-                }
-                if (ok && height != null && width != null) {
-                    ok = Math.min(height, width) <= mSmallerDimensionUpperLimit;
-
-                    final int widthInBlocks = Utils.divUp(width, mBlockWidth);
-                    final int heightInBlocks = Utils.divUp(height, mBlockHeight);
-                    final int blockCount = widthInBlocks * heightInBlocks;
-                    ok = ok && mBlockCountRange.contains(blockCount)
-                            && mBlockAspectRatioRange.contains(
-                                    new Rational(widthInBlocks, heightInBlocks))
-                            && mAspectRatioRange.contains(new Rational(width, height));
-                    if (ok && rate != null) {
-                        double blocksPerSec = blockCount * rate;
-                        ok = mBlocksPerSecondRange.contains(
-                                Utils.longRangeFor(blocksPerSec));
-                    }
-                }
-                return ok;
-            }
-
-            /**
-             * @hide
-             * @throws java.lang.ClassCastException */
-            public boolean supportsFormat(MediaFormat format) {
-                final Map<String, Object> map = format.getMap();
-                Integer width = (Integer)map.get(MediaFormat.KEY_WIDTH);
-                Integer height = (Integer)map.get(MediaFormat.KEY_HEIGHT);
-                Double rate = (Double)map.get(MediaFormat.KEY_FRAME_RATE);
-
-                // we ignore color-format for now as it is not reliably reported by codec
-
-                return supports(width, height, rate);
-            }
-
-            /* no public constructor */
-            private VideoCapabilities() { }
-
-            /** @hide */
-            public static VideoCapabilities create(
-                    MediaFormat info, CodecCapabilities parent) {
-                VideoCapabilities caps = new VideoCapabilities();
-                caps.init(info, parent);
-                return caps;
-            }
-
-            /** @hide */
-            public void init(MediaFormat info, CodecCapabilities parent) {
-                super.init(info, parent);
-                initWithPlatformLimits();
-                applyLevelLimits();
-                parseFromInfo(info);
-                updateLimits();
-            }
-
-            /** @hide */
-            public Size getBlockSize() {
-                return new Size(mBlockWidth, mBlockHeight);
-            }
-
-            /** @hide */
-            public Range<Integer> getBlockCountRange() {
-                return mBlockCountRange;
-            }
-
-            /** @hide */
-            public Range<Long> getBlocksPerSecondRange() {
-                return mBlocksPerSecondRange;
-            }
-
-            /** @hide */
-            public Range<Rational> getAspectRatioRange(boolean blocks) {
-                return blocks ? mBlockAspectRatioRange : mAspectRatioRange;
-            }
-
-            private void initWithPlatformLimits() {
-                mWidthRange  = SIZE_RANGE;
-                mHeightRange = SIZE_RANGE;
-                mFrameRateRange = FRAME_RATE_RANGE;
-
-                mHorizontalBlockRange = SIZE_RANGE;
-                mVerticalBlockRange   = SIZE_RANGE;
-
-                // full positive ranges are supported as these get calculated
-                mBlockCountRange      = POSITIVE_INTEGERS;
-                mBlocksPerSecondRange = POSITIVE_LONGS;
-
-                mBlockAspectRatioRange = POSITIVE_RATIONALS;
-                mAspectRatioRange      = POSITIVE_RATIONALS;
-
-                // YUV 4:2:0 requires 2:2 alignment
-                mWidthAlignment = 2;
-                mHeightAlignment = 2;
-                mBlockWidth = 2;
-                mBlockHeight = 2;
-                mSmallerDimensionUpperLimit = SIZE_RANGE.getUpper();
-            }
-
-            private void parseFromInfo(MediaFormat info) {
-                final Map<String, Object> map = info.getMap();
-                Size blockSize = new Size(mBlockWidth, mBlockHeight);
-                Size alignment = new Size(mWidthAlignment, mHeightAlignment);
-                Range<Integer> counts = null, widths = null, heights = null;
-                Range<Integer> frameRates = null;
-                Range<Long> blockRates = null;
-                Range<Rational> ratios = null, blockRatios = null;
-
-                blockSize = Utils.parseSize(map.get("block-size"), blockSize);
-                alignment = Utils.parseSize(map.get("alignment"), alignment);
-                counts = Utils.parseIntRange(map.get("block-count-range"), null);
-                blockRates =
-                    Utils.parseLongRange(map.get("blocks-per-second-range"), null);
-                {
-                    Object o = map.get("size-range");
-                    Pair<Size, Size> sizeRange = Utils.parseSizeRange(o);
-                    if (sizeRange != null) {
-                        try {
-                            widths = Range.create(
-                                    sizeRange.first.getWidth(),
-                                    sizeRange.second.getWidth());
-                            heights = Range.create(
-                                    sizeRange.first.getHeight(),
-                                    sizeRange.second.getHeight());
-                        } catch (IllegalArgumentException e) {
-                            Log.w(TAG, "could not parse size range '" + o + "'");
-                            widths = null;
-                            heights = null;
-                        }
-                    }
-                }
-                // 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 (Integer.valueOf(1).equals(map.get("feature-can-swap-width-height"))) {
-                    if (widths != null) {
-                        mSmallerDimensionUpperLimit =
-                            Math.min(widths.getUpper(), heights.getUpper());
-                        widths = heights = widths.extend(heights);
-                    } else {
-                        Log.w(TAG, "feature can-swap-width-height is best used with size-range");
-                        mSmallerDimensionUpperLimit =
-                            Math.min(mWidthRange.getUpper(), mHeightRange.getUpper());
-                        mWidthRange = mHeightRange = mWidthRange.extend(mHeightRange);
-                    }
-                }
-
-                ratios = Utils.parseRationalRange(
-                        map.get("block-aspect-ratio-range"), null);
-                blockRatios = Utils.parseRationalRange(
-                        map.get("pixel-aspect-ratio-range"), null);
-                frameRates = Utils.parseIntRange(map.get("frame-rate-range"), null);
-                if (frameRates != null) {
-                    try {
-                        frameRates = frameRates.intersect(FRAME_RATE_RANGE);
-                    } catch (IllegalArgumentException e) {
-                        Log.w(TAG, "frame rate range (" + frameRates
-                                + ") is out of limits: " + FRAME_RATE_RANGE);
-                        frameRates = null;
-                    }
-                }
-
-                checkPowerOfTwo(
-                        blockSize.getWidth(), "block-size width must be power of two");
-                checkPowerOfTwo(
-                        blockSize.getHeight(), "block-size height must be power of two");
-
-                checkPowerOfTwo(
-                        alignment.getWidth(), "alignment width must be power of two");
-                checkPowerOfTwo(
-                        alignment.getHeight(), "alignment height must be power of two");
-
-                // update block-size and alignment
-                applyMacroBlockLimits(
-                        Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,
-                        Long.MAX_VALUE, blockSize.getWidth(), blockSize.getHeight(),
-                        alignment.getWidth(), alignment.getHeight());
-
-                if ((mParent.mError & ERROR_UNSUPPORTED) != 0) {
-                    // codec supports profiles that we don't know.
-                    // Use supplied values clipped to platform limits
-                    if (widths != null) {
-                        mWidthRange = SIZE_RANGE.intersect(widths);
-                    }
-                    if (heights != null) {
-                        mHeightRange = SIZE_RANGE.intersect(heights);
-                    }
-                    if (counts != null) {
-                        mBlockCountRange = POSITIVE_INTEGERS.intersect(
-                                Utils.factorRange(counts, mBlockWidth * mBlockHeight
-                                        / blockSize.getWidth() / blockSize.getHeight()));
-                    }
-                    if (blockRates != null) {
-                        mBlocksPerSecondRange = POSITIVE_LONGS.intersect(
-                                Utils.factorRange(blockRates, mBlockWidth * mBlockHeight
-                                        / blockSize.getWidth() / blockSize.getHeight()));
-                    }
-                    if (blockRatios != null) {
-                        mBlockAspectRatioRange = POSITIVE_RATIONALS.intersect(
-                                Utils.scaleRange(blockRatios,
-                                        mBlockHeight / blockSize.getHeight(),
-                                        mBlockWidth / blockSize.getWidth()));
-                    }
-                    if (ratios != null) {
-                        mAspectRatioRange = POSITIVE_RATIONALS.intersect(ratios);
-                    }
-                    if (frameRates != null) {
-                        mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates);
-                    }
-                } else {
-                    // no unsupported profile/levels, so restrict values to known limits
-                    if (widths != null) {
-                        mWidthRange = mWidthRange.intersect(widths);
-                    }
-                    if (heights != null) {
-                        mHeightRange = mHeightRange.intersect(heights);
-                    }
-                    if (counts != null) {
-                        mBlockCountRange = mBlockCountRange.intersect(
-                                Utils.factorRange(counts, mBlockWidth * mBlockHeight
-                                        / blockSize.getWidth() / blockSize.getHeight()));
-                    }
-                    if (blockRates != null) {
-                        mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
-                                Utils.factorRange(blockRates, mBlockWidth * mBlockHeight
-                                        / blockSize.getWidth() / blockSize.getHeight()));
-                    }
-                    if (blockRatios != null) {
-                        mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
-                                Utils.scaleRange(blockRatios,
-                                        mBlockHeight / blockSize.getHeight(),
-                                        mBlockWidth / blockSize.getWidth()));
-                    }
-                    if (ratios != null) {
-                        mAspectRatioRange = mAspectRatioRange.intersect(ratios);
-                    }
-                    if (frameRates != null) {
-                        mFrameRateRange = mFrameRateRange.intersect(frameRates);
-                    }
-                }
-                updateLimits();
-            }
-
-            private int checkPowerOfTwo(int value, String message) {
-                if ((value & (value - 1)) != 0) {
-                    throw new IllegalArgumentException(message);
-                }
-                return value;
-            }
-
-            private void applyBlockLimits(
-                    int blockWidth, int blockHeight,
-                    Range<Integer> counts, Range<Long> rates, Range<Rational> ratios) {
-                checkPowerOfTwo(blockWidth, "blockWidth must be a power of two");
-                checkPowerOfTwo(blockHeight, "blockHeight must be a power of two");
-
-                final int newBlockWidth = Math.max(blockWidth, mBlockWidth);
-                final int newBlockHeight = Math.max(blockHeight, mBlockHeight);
-
-                // factor will always be a power-of-2
-                int factor =
-                    newBlockWidth * newBlockHeight / mBlockWidth / mBlockHeight;
-                if (factor != 1) {
-                    mBlockCountRange = Utils.factorRange(mBlockCountRange, factor);
-                    mBlocksPerSecondRange = Utils.factorRange(
-                            mBlocksPerSecondRange, factor);
-                    mBlockAspectRatioRange = Utils.scaleRange(
-                            mBlockAspectRatioRange,
-                            newBlockHeight / mBlockHeight,
-                            newBlockWidth / mBlockWidth);
-                    mHorizontalBlockRange = Utils.factorRange(
-                            mHorizontalBlockRange, newBlockWidth / mBlockWidth);
-                    mVerticalBlockRange = Utils.factorRange(
-                            mVerticalBlockRange, newBlockHeight / mBlockHeight);
-                }
-                factor = newBlockWidth * newBlockHeight / blockWidth / blockHeight;
-                if (factor != 1) {
-                    counts = Utils.factorRange(counts, factor);
-                    rates = Utils.factorRange(rates, factor);
-                    ratios = Utils.scaleRange(
-                            ratios, newBlockHeight / blockHeight,
-                            newBlockWidth / blockWidth);
-                }
-                mBlockCountRange = mBlockCountRange.intersect(counts);
-                mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(rates);
-                mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(ratios);
-                mBlockWidth = newBlockWidth;
-                mBlockHeight = newBlockHeight;
-            }
-
-            private void applyAlignment(int widthAlignment, int heightAlignment) {
-                checkPowerOfTwo(widthAlignment, "widthAlignment must be a power of two");
-                checkPowerOfTwo(heightAlignment, "heightAlignment must be a power of two");
-
-                if (widthAlignment > mBlockWidth || heightAlignment > mBlockHeight) {
-                    // maintain assumption that 0 < alignment <= block-size
-                    applyBlockLimits(
-                            Math.max(widthAlignment, mBlockWidth),
-                            Math.max(heightAlignment, mBlockHeight),
-                            POSITIVE_INTEGERS, POSITIVE_LONGS, POSITIVE_RATIONALS);
-                }
-
-                mWidthAlignment = Math.max(widthAlignment, mWidthAlignment);
-                mHeightAlignment = Math.max(heightAlignment, mHeightAlignment);
-
-                mWidthRange = Utils.alignRange(mWidthRange, mWidthAlignment);
-                mHeightRange = Utils.alignRange(mHeightRange, mHeightAlignment);
-            }
-
-            private void updateLimits() {
-                // pixels -> blocks <- counts
-                mHorizontalBlockRange = mHorizontalBlockRange.intersect(
-                        Utils.factorRange(mWidthRange, mBlockWidth));
-                mHorizontalBlockRange = mHorizontalBlockRange.intersect(
-                        Range.create(
-                                mBlockCountRange.getLower() / mVerticalBlockRange.getUpper(),
-                                mBlockCountRange.getUpper() / mVerticalBlockRange.getLower()));
-                mVerticalBlockRange = mVerticalBlockRange.intersect(
-                        Utils.factorRange(mHeightRange, mBlockHeight));
-                mVerticalBlockRange = mVerticalBlockRange.intersect(
-                        Range.create(
-                                mBlockCountRange.getLower() / mHorizontalBlockRange.getUpper(),
-                                mBlockCountRange.getUpper() / mHorizontalBlockRange.getLower()));
-                mBlockCountRange = mBlockCountRange.intersect(
-                        Range.create(
-                                mHorizontalBlockRange.getLower()
-                                        * mVerticalBlockRange.getLower(),
-                                mHorizontalBlockRange.getUpper()
-                                        * mVerticalBlockRange.getUpper()));
-                mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
-                        new Rational(
-                                mHorizontalBlockRange.getLower(), mVerticalBlockRange.getUpper()),
-                        new Rational(
-                                mHorizontalBlockRange.getUpper(), mVerticalBlockRange.getLower()));
-
-                // blocks -> pixels
-                mWidthRange = mWidthRange.intersect(
-                        (mHorizontalBlockRange.getLower() - 1) * mBlockWidth + mWidthAlignment,
-                        mHorizontalBlockRange.getUpper() * mBlockWidth);
-                mHeightRange = mHeightRange.intersect(
-                        (mVerticalBlockRange.getLower() - 1) * mBlockHeight + mHeightAlignment,
-                        mVerticalBlockRange.getUpper() * mBlockHeight);
-                mAspectRatioRange = mAspectRatioRange.intersect(
-                        new Rational(mWidthRange.getLower(), mHeightRange.getUpper()),
-                        new Rational(mWidthRange.getUpper(), mHeightRange.getLower()));
-
-                mSmallerDimensionUpperLimit = Math.min(
-                        mSmallerDimensionUpperLimit,
-                        Math.min(mWidthRange.getUpper(), mHeightRange.getUpper()));
-
-                // blocks -> rate
-                mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
-                        mBlockCountRange.getLower() * (long)mFrameRateRange.getLower(),
-                        mBlockCountRange.getUpper() * (long)mFrameRateRange.getUpper());
-                mFrameRateRange = mFrameRateRange.intersect(
-                        (int)(mBlocksPerSecondRange.getLower()
-                                / mBlockCountRange.getUpper()),
-                        (int)(mBlocksPerSecondRange.getUpper()
-                                / (double)mBlockCountRange.getLower()));
-            }
-
-            private void applyMacroBlockLimits(
-                    int maxHorizontalBlocks, int maxVerticalBlocks,
-                    int maxBlocks, long maxBlocksPerSecond,
-                    int blockWidth, int blockHeight,
-                    int widthAlignment, int heightAlignment) {
-                applyAlignment(widthAlignment, heightAlignment);
-                applyBlockLimits(
-                        blockWidth, blockHeight, Range.create(1, maxBlocks),
-                        Range.create(1L, maxBlocksPerSecond),
-                        Range.create(
-                                new Rational(1, maxVerticalBlocks),
-                                new Rational(maxHorizontalBlocks, 1)));
-                mHorizontalBlockRange =
-                        mHorizontalBlockRange.intersect(
-                                1, maxHorizontalBlocks / (mBlockWidth / blockWidth));
-                mVerticalBlockRange =
-                        mVerticalBlockRange.intersect(
-                                1, maxVerticalBlocks / (mBlockHeight / blockHeight));
-            }
-
-            private void applyLevelLimits() {
-                int maxBlocksPerSecond = 0;
-                int maxBlocks = 0;
-                int maxBps = 0;
-                int maxDPBBlocks = 0;
-
-                int errors = ERROR_NONE_SUPPORTED;
-                CodecProfileLevel[] profileLevels = mParent.profileLevels;
-                String mime = mParent.getMime();
-
-                if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC)) {
-                    maxBlocks = 99;
-                    maxBlocksPerSecond = 1485;
-                    maxBps = 64000;
-                    maxDPBBlocks = 396;
-                    for (CodecProfileLevel profileLevel: profileLevels) {
-                        int MBPS = 0, FS = 0, BR = 0, DPB = 0;
-                        boolean supported = true;
-                        switch (profileLevel.level) {
-                            case CodecProfileLevel.AVCLevel1:
-                                MBPS =    1485; FS =    99; BR =     64; DPB =    396; break;
-                            case CodecProfileLevel.AVCLevel1b:
-                                MBPS =    1485; FS =    99; BR =    128; DPB =    396; break;
-                            case CodecProfileLevel.AVCLevel11:
-                                MBPS =    3000; FS =   396; BR =    192; DPB =    900; break;
-                            case CodecProfileLevel.AVCLevel12:
-                                MBPS =    6000; FS =   396; BR =    384; DPB =   2376; break;
-                            case CodecProfileLevel.AVCLevel13:
-                                MBPS =   11880; FS =   396; BR =    768; DPB =   2376; break;
-                            case CodecProfileLevel.AVCLevel2:
-                                MBPS =   11880; FS =   396; BR =   2000; DPB =   2376; break;
-                            case CodecProfileLevel.AVCLevel21:
-                                MBPS =   19800; FS =   792; BR =   4000; DPB =   4752; break;
-                            case CodecProfileLevel.AVCLevel22:
-                                MBPS =   20250; FS =  1620; BR =   4000; DPB =   8100; break;
-                            case CodecProfileLevel.AVCLevel3:
-                                MBPS =   40500; FS =  1620; BR =  10000; DPB =   8100; break;
-                            case CodecProfileLevel.AVCLevel31:
-                                MBPS =  108000; FS =  3600; BR =  14000; DPB =  18000; break;
-                            case CodecProfileLevel.AVCLevel32:
-                                MBPS =  216000; FS =  5120; BR =  20000; DPB =  20480; break;
-                            case CodecProfileLevel.AVCLevel4:
-                                MBPS =  245760; FS =  8192; BR =  20000; DPB =  32768; break;
-                            case CodecProfileLevel.AVCLevel41:
-                                MBPS =  245760; FS =  8192; BR =  50000; DPB =  32768; break;
-                            case CodecProfileLevel.AVCLevel42:
-                                MBPS =  522240; FS =  8704; BR =  50000; DPB =  34816; break;
-                            case CodecProfileLevel.AVCLevel5:
-                                MBPS =  589824; FS = 22080; BR = 135000; DPB = 110400; break;
-                            case CodecProfileLevel.AVCLevel51:
-                                MBPS =  983040; FS = 36864; BR = 240000; DPB = 184320; break;
-                            case CodecProfileLevel.AVCLevel52:
-                                MBPS = 2073600; FS = 36864; BR = 240000; DPB = 184320; break;
-                            default:
-                                Log.w(TAG, "Unrecognized level "
-                                        + profileLevel.level + " for " + mime);
-                                errors |= ERROR_UNRECOGNIZED;
-                        }
-                        switch (profileLevel.profile) {
-                            case CodecProfileLevel.AVCProfileHigh:
-                                BR *= 1250; break;
-                            case CodecProfileLevel.AVCProfileHigh10:
-                                BR *= 3000; break;
-                            case CodecProfileLevel.AVCProfileExtended:
-                            case CodecProfileLevel.AVCProfileHigh422:
-                            case CodecProfileLevel.AVCProfileHigh444:
-                                Log.w(TAG, "Unsupported profile "
-                                        + profileLevel.profile + " for " + mime);
-                                errors |= ERROR_UNSUPPORTED;
-                                supported = false;
-                                // fall through - treat as base profile
-                            case CodecProfileLevel.AVCProfileBaseline:
-                            case CodecProfileLevel.AVCProfileMain:
-                                BR *= 1000; break;
-                            default:
-                                Log.w(TAG, "Unrecognized profile "
-                                        + profileLevel.profile + " for " + mime);
-                                errors |= ERROR_UNRECOGNIZED;
-                                BR *= 1000;
-                        }
-                        if (supported) {
-                            errors &= ~ERROR_NONE_SUPPORTED;
-                        }
-                        maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
-                        maxBlocks = Math.max(FS, maxBlocks);
-                        maxBps = Math.max(BR, maxBps);
-                        maxDPBBlocks = Math.max(maxDPBBlocks, DPB);
-                    }
-
-                    int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8));
-                    applyMacroBlockLimits(
-                            maxLengthInBlocks, maxLengthInBlocks,
-                            maxBlocks, maxBlocksPerSecond,
-                            16 /* blockWidth */, 16 /* blockHeight */,
-                            1 /* widthAlignment */, 1 /* heightAlignment */);
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
-                    int maxWidth = 11, maxHeight = 9, maxRate = 15;
-                    maxBlocks = 99;
-                    maxBlocksPerSecond = 1485;
-                    maxBps = 64000;
-                    for (CodecProfileLevel profileLevel: profileLevels) {
-                        int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0;
-                        boolean supported = true;
-                        switch (profileLevel.profile) {
-                            case CodecProfileLevel.MPEG4ProfileSimple:
-                                switch (profileLevel.level) {
-                                    case CodecProfileLevel.MPEG4Level0:
-                                        FR = 15; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
-                                    case CodecProfileLevel.MPEG4Level1:
-                                        FR = 30; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
-                                    case CodecProfileLevel.MPEG4Level0b:
-                                        FR = 30; W = 11; H =  9; MBPS =  1485; FS =  99; BR = 128; break;
-                                    case CodecProfileLevel.MPEG4Level2:
-                                        FR = 30; W = 22; H = 18; MBPS =  5940; FS = 396; BR = 128; break;
-                                    case CodecProfileLevel.MPEG4Level3:
-                                        FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384; break;
-                                    case CodecProfileLevel.MPEG4Level4:
-                                    case CodecProfileLevel.MPEG4Level4a:
-                                    case CodecProfileLevel.MPEG4Level5:
-                                        // While MPEG4 SP does not have level 4 or 5, some vendors
-                                        // report it. Use the same limits as level 3, but mark as
-                                        // unsupported.
-                                        FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384;
-                                        supported = false;
-                                        break;
-                                    default:
-                                        Log.w(TAG, "Unrecognized profile/level "
-                                                + profileLevel.profile + "/"
-                                                + profileLevel.level + " for " + mime);
-                                        errors |= ERROR_UNRECOGNIZED;
-                                }
-                                break;
-                            case CodecProfileLevel.MPEG4ProfileAdvancedSimple:
-                                switch (profileLevel.level) {
-                                    case CodecProfileLevel.MPEG4Level0:
-                                    case CodecProfileLevel.MPEG4Level1:
-                                        FR = 30; W = 11; H =  9; MBPS =  2970; FS =   99; BR =  128; break;
-                                    case CodecProfileLevel.MPEG4Level2:
-                                        FR = 30; W = 22; H = 18; MBPS =  5940; FS =  396; BR =  384; break;
-                                    case CodecProfileLevel.MPEG4Level3:
-                                        FR = 30; W = 22; H = 18; MBPS = 11880; FS =  396; BR =  768; break;
-                                    // case CodecProfileLevel.MPEG4Level3b:
-                                    // TODO: MPEG4 level 3b is not defined in OMX
-                                    //  MBPS = 11880; FS =  396; BR = 1500; break;
-                                    case CodecProfileLevel.MPEG4Level4:
-                                    case CodecProfileLevel.MPEG4Level4a:
-                                        // TODO: MPEG4 level 4a is not defined in spec
-                                        FR = 30; W = 44; H = 36; MBPS = 23760; FS =  792; BR = 3000; break;
-                                    case CodecProfileLevel.MPEG4Level5:
-                                        FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 8000; break;
-                                    default:
-                                        Log.w(TAG, "Unrecognized profile/level "
-                                                + profileLevel.profile + "/"
-                                                + profileLevel.level + " for " + mime);
-                                        errors |= ERROR_UNRECOGNIZED;
-                                }
-                                break;
-                            case CodecProfileLevel.MPEG4ProfileMain:             // 2-4
-                            case CodecProfileLevel.MPEG4ProfileNbit:             // 2
-                            case CodecProfileLevel.MPEG4ProfileAdvancedRealTime: // 1-4
-                            case CodecProfileLevel.MPEG4ProfileCoreScalable:     // 1-3
-                            case CodecProfileLevel.MPEG4ProfileAdvancedCoding:   // 1-4
-                            case CodecProfileLevel.MPEG4ProfileCore:             // 1-2
-                            case CodecProfileLevel.MPEG4ProfileAdvancedCore:     // 1-4
-                            case CodecProfileLevel.MPEG4ProfileSimpleScalable:   // 0-2
-                            case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3
-                            case CodecProfileLevel.MPEG4ProfileHybrid:           // 1-2
-                            case CodecProfileLevel.MPEG4ProfileBasicAnimated:    // 1-2
-                            case CodecProfileLevel.MPEG4ProfileScalableTexture:  // 1
-                            case CodecProfileLevel.MPEG4ProfileSimpleFace:       // 1-2
-                            case CodecProfileLevel.MPEG4ProfileSimpleFBA:        // 1-2
-                                Log.i(TAG, "Unsupported profile "
-                                        + profileLevel.profile + " for " + mime);
-                                errors |= ERROR_UNSUPPORTED;
-                                supported = false;
-                                break;
-                            default:
-                                Log.w(TAG, "Unrecognized profile "
-                                        + profileLevel.profile + " for " + mime);
-                                errors |= ERROR_UNRECOGNIZED;
-                        }
-                        if (supported) {
-                            errors &= ~ERROR_NONE_SUPPORTED;
-                        }
-                        maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
-                        maxBlocks = Math.max(FS, maxBlocks);
-                        maxBps = Math.max(BR * 1000, maxBps);
-                        maxWidth = Math.max(W, maxWidth);
-                        maxHeight = Math.max(H, maxHeight);
-                        maxRate = Math.max(FR, maxRate);
-                    }
-                    applyMacroBlockLimits(maxWidth, maxHeight,
-                            maxBlocks, maxBlocksPerSecond,
-                            16 /* blockWidth */, 16 /* blockHeight */,
-                            1 /* widthAlignment */, 1 /* heightAlignment */);
-                    mFrameRateRange = mFrameRateRange.intersect(12, maxRate);
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
-                    int maxWidth = 11, maxHeight = 9, maxRate = 15;
-                    maxBlocks = 99;
-                    maxBlocksPerSecond = 1485;
-                    maxBps = 64000;
-                    for (CodecProfileLevel profileLevel: profileLevels) {
-                        int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0;
-                        switch (profileLevel.level) {
-                            case CodecProfileLevel.H263Level10:
-                                FR = 15; W = 11; H =  9; BR =   1; MBPS =  W * H * FR; break;
-                            case CodecProfileLevel.H263Level20:
-                                // only supports CIF, 0..QCIF
-                                FR = 30; W = 22; H = 18; BR =   2; MBPS =  W * H * FR; break;
-                            case CodecProfileLevel.H263Level30:
-                                // only supports CIF, 0..QCIF
-                                FR = 30; W = 22; H = 18; BR =   6; MBPS =  W * H * FR; break;
-                            case CodecProfileLevel.H263Level40:
-                                // only supports CIF, 0..QCIF
-                                FR = 30; W = 22; H = 18; BR =  32; MBPS =  W * H * FR; break;
-                            case CodecProfileLevel.H263Level45:
-                                // only implies level 10 support
-                                FR = 30; W = 11; H =  9; BR =   2; MBPS =  W * H * FR; break;
-                            case CodecProfileLevel.H263Level50:
-                                // only supports 50fps for H > 15
-                                FR = 60; W = 22; H = 18; BR =  64; MBPS =  W * H * 50; break;
-                            case CodecProfileLevel.H263Level60:
-                                // only supports 50fps for H > 15
-                                FR = 60; W = 45; H = 18; BR = 128; MBPS =  W * H * 50; break;
-                            case CodecProfileLevel.H263Level70:
-                                // only supports 50fps for H > 30
-                                FR = 60; W = 45; H = 36; BR = 256; MBPS =  W * H * 50; break;
-                            default:
-                                Log.w(TAG, "Unrecognized profile/level " + profileLevel.profile
-                                        + "/" + profileLevel.level + " for " + mime);
-                                errors |= ERROR_UNRECOGNIZED;
-                        }
-                        switch (profileLevel.profile) {
-                            case CodecProfileLevel.H263ProfileBackwardCompatible:
-                            case CodecProfileLevel.H263ProfileBaseline:
-                            case CodecProfileLevel.H263ProfileH320Coding:
-                            case CodecProfileLevel.H263ProfileHighCompression:
-                            case CodecProfileLevel.H263ProfileHighLatency:
-                            case CodecProfileLevel.H263ProfileInterlace:
-                            case CodecProfileLevel.H263ProfileInternet:
-                            case CodecProfileLevel.H263ProfileISWV2:
-                            case CodecProfileLevel.H263ProfileISWV3:
-                                break;
-                            default:
-                                Log.w(TAG, "Unrecognized profile "
-                                        + profileLevel.profile + " for " + mime);
-                                errors |= ERROR_UNRECOGNIZED;
-                        }
-                        errors &= ~ERROR_NONE_SUPPORTED;
-                        maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
-                        maxBlocks = Math.max(W * H, maxBlocks);
-                        maxBps = Math.max(BR * 64000, maxBps);
-                        maxWidth = Math.max(W, maxWidth);
-                        maxHeight = Math.max(H, maxHeight);
-                        maxRate = Math.max(FR, maxRate);
-                    }
-                    applyMacroBlockLimits(maxWidth, maxHeight,
-                            maxBlocks, maxBlocksPerSecond,
-                            16 /* blockWidth */, 16 /* blockHeight */,
-                            1 /* widthAlignment */, 1 /* heightAlignment */);
-                    mFrameRateRange = Range.create(1, maxRate);
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) ||
-                        mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
-                    maxBlocks = maxBlocksPerSecond = Integer.MAX_VALUE;
-
-                    // TODO: set to 100Mbps for now, need a number for VPX
-                    maxBps = 100000000;
-
-                    // profile levels are not indicative for VPx, but verify
-                    // them nonetheless
-                    for (CodecProfileLevel profileLevel: profileLevels) {
-                        switch (profileLevel.level) {
-                            case CodecProfileLevel.VP8Level_Version0:
-                            case CodecProfileLevel.VP8Level_Version1:
-                            case CodecProfileLevel.VP8Level_Version2:
-                            case CodecProfileLevel.VP8Level_Version3:
-                                break;
-                            default:
-                                Log.w(TAG, "Unrecognized level "
-                                        + profileLevel.level + " for " + mime);
-                                errors |= ERROR_UNRECOGNIZED;
-                        }
-                        switch (profileLevel.profile) {
-                            case CodecProfileLevel.VP8ProfileMain:
-                                break;
-                            default:
-                                Log.w(TAG, "Unrecognized profile "
-                                        + profileLevel.profile + " for " + mime);
-                                errors |= ERROR_UNRECOGNIZED;
-                        }
-                        errors &= ~ERROR_NONE_SUPPORTED;
-                    }
-
-                    final int blockSize =
-                        mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) ? 16 : 8;
-                    applyMacroBlockLimits(Short.MAX_VALUE, Short.MAX_VALUE,
-                            maxBlocks, maxBlocksPerSecond, blockSize, blockSize,
-                            1 /* widthAlignment */, 1 /* heightAlignment */);
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
-                    maxBlocks = 36864;
-                    maxBlocksPerSecond = maxBlocks * 15;
-                    maxBps = 128000;
-                    for (CodecProfileLevel profileLevel: profileLevels) {
-                        double FR = 0;
-                        int FS = 0;
-                        int BR = 0;
-                        switch (profileLevel.level) {
-                            case CodecProfileLevel.HEVCMainTierLevel1:
-                            case CodecProfileLevel.HEVCHighTierLevel1:
-                                FR =    15; FS =    36864; BR =    128; break;
-                            case CodecProfileLevel.HEVCMainTierLevel2:
-                            case CodecProfileLevel.HEVCHighTierLevel2:
-                                FR =    30; FS =   122880; BR =   1500; break;
-                            case CodecProfileLevel.HEVCMainTierLevel21:
-                            case CodecProfileLevel.HEVCHighTierLevel21:
-                                FR =    30; FS =   245760; BR =   3000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel3:
-                            case CodecProfileLevel.HEVCHighTierLevel3:
-                                FR =    30; FS =   552960; BR =   6000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel31:
-                            case CodecProfileLevel.HEVCHighTierLevel31:
-                                FR = 33.75; FS =   983040; BR =  10000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel4:
-                                FR =    30; FS =  2228224; BR =  12000; break;
-                            case CodecProfileLevel.HEVCHighTierLevel4:
-                                FR =    30; FS =  2228224; BR =  30000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel41:
-                                FR =    60; FS =  2228224; BR =  20000; break;
-                            case CodecProfileLevel.HEVCHighTierLevel41:
-                                FR =    60; FS =  2228224; BR =  50000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel5:
-                                FR =    30; FS =  8912896; BR =  25000; break;
-                            case CodecProfileLevel.HEVCHighTierLevel5:
-                                FR =    30; FS =  8912896; BR = 100000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel51:
-                                FR =    60; FS =  8912896; BR =  40000; break;
-                            case CodecProfileLevel.HEVCHighTierLevel51:
-                                FR =    60; FS =  8912896; BR = 160000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel52:
-                                FR =   120; FS =  8912896; BR =  60000; break;
-                            case CodecProfileLevel.HEVCHighTierLevel52:
-                                FR =   120; FS =  8912896; BR = 240000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel6:
-                                FR =    30; FS = 35651584; BR =  60000; break;
-                            case CodecProfileLevel.HEVCHighTierLevel6:
-                                FR =    30; FS = 35651584; BR = 240000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel61:
-                                FR =    60; FS = 35651584; BR = 120000; break;
-                            case CodecProfileLevel.HEVCHighTierLevel61:
-                                FR =    60; FS = 35651584; BR = 480000; break;
-                            case CodecProfileLevel.HEVCMainTierLevel62:
-                                FR =   120; FS = 35651584; BR = 240000; break;
-                            case CodecProfileLevel.HEVCHighTierLevel62:
-                                FR =   120; FS = 35651584; BR = 800000; break;
-                            default:
-                                Log.w(TAG, "Unrecognized level "
-                                        + profileLevel.level + " for " + mime);
-                                errors |= ERROR_UNRECOGNIZED;
-                        }
-                        switch (profileLevel.profile) {
-                            case CodecProfileLevel.HEVCProfileMain:
-                            case CodecProfileLevel.HEVCProfileMain10:
-                                break;
-                            default:
-                                Log.w(TAG, "Unrecognized profile "
-                                        + profileLevel.profile + " for " + mime);
-                                errors |= ERROR_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;
-                        */
-
-                        errors &= ~ERROR_NONE_SUPPORTED;
-                        maxBlocksPerSecond = Math.max((int)(FR * FS), maxBlocksPerSecond);
-                        maxBlocks = Math.max(FS, maxBlocks);
-                        maxBps = Math.max(BR * 1000, maxBps);
-                    }
-
-                    int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8));
-                    // CTBs are at least 8x8
-                    maxBlocks = Utils.divUp(maxBlocks, 8 * 8);
-                    maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, 8 * 8);
-                    maxLengthInBlocks = Utils.divUp(maxLengthInBlocks, 8);
-
-                    applyMacroBlockLimits(
-                            maxLengthInBlocks, maxLengthInBlocks,
-                            maxBlocks, maxBlocksPerSecond,
-                            8 /* blockWidth */, 8 /* blockHeight */,
-                            1 /* widthAlignment */, 1 /* heightAlignment */);
-                } else {
-                    Log.w(TAG, "Unsupported mime " + mime);
-                    // using minimal bitrate here.  should be overriden by
-                    // info from media_codecs.xml
-                    maxBps = 64000;
-                    errors |= ERROR_UNSUPPORTED;
-                }
-                mBitrateRange = Range.create(1, maxBps);
-                mParent.mError |= errors;
-            }
-        };
-
-        VideoCapabilities mVideoCaps;
-
         private boolean isVideo() {
             return mVideoCaps != null;
         }
@@ -1624,16 +393,28 @@
         /**
          * Returns the video capabilities or {@code null} if this is not a video codec.
          */
-        public final VideoCapabilities getVideoCapabilities() {
+        public VideoCapabilities getVideoCapabilities() {
             return mVideoCaps;
         }
 
+        /** @hide */
+        public CodecCapabilities dup() {
+            return new CodecCapabilities(
+                // clone writable arrays
+                Arrays.copyOf(profileLevels, profileLevels.length),
+                Arrays.copyOf(colorFormats, colorFormats.length),
+                isEncoder(),
+                mFlagsVerified,
+                mDefaultFormat,
+                mCapabilitiesInfo);
+        }
+
         /**
          * Retrieve the codec capabilities for a certain {@code mime type}, {@code
          * profile} and {@code level}.  If the type, or profile-level combination
          * is not understood by the framework, it returns null.
          */
-        public static final CodecCapabilities CreateFromProfileLevel(
+        public static CodecCapabilities CreateFromProfileLevel(
                 String mime, int profile, int level) {
             CodecProfileLevel pl = new CodecProfileLevel();
             pl.profile = profile;
@@ -1699,282 +480,1503 @@
                 // TODO restrict features by mFlagsVerified once all codecs reliably verify them
             }
         }
+    }
+
+    /**
+     * A class that supports querying the audio capabilities of a codec.
+     */
+    public static final class AudioCapabilities {
+        private static final String TAG = "AudioCapabilities";
+        private CodecCapabilities mParent;
+        private Range<Integer> mBitrateRange;
+
+        private int[] mSampleRates;
+        private Range<Integer>[] mSampleRateRanges;
+        private int mMaxInputChannelCount;
+
+        private static final int MAX_INPUT_CHANNEL_COUNT = 30;
 
         /**
-         * A class that supports querying the audio capabilities of a codec.
+         * Returns the range of supported bitrates in bits/second.
          */
-        public static final class AudioCapabilities extends BaseCapabilities {
-            private static final String TAG = "AudioCapabilities";
-
-            private int[] mSampleRates;
-            private Range<Integer>[] mSampleRateRanges;
-            private int mMaxInputChannelCount;
-
-            private static final int MAX_INPUT_CHANNEL_COUNT = 30;
-
-            /**
-             * Returns the array of supported sample rates if the codec
-             * supports only discrete values.  Otherwise, it returns
-             * {@code null}.  The array is sorted in ascending order.
-             */
-            public final int[] getSupportedSampleRates() {
-                return Arrays.copyOf(mSampleRates, mSampleRates.length);
-            }
-
-            /**
-             * Returns the array of supported sample rate ranges.  The
-             * array is sorted in ascending order, and the ranges are
-             * distinct.
-             */
-            public final Range<Integer>[] getSupportedSampleRateRanges() {
-                return Arrays.copyOf(mSampleRateRanges, mSampleRateRanges.length);
-            }
-
-            /**
-             * Returns the maximum number of input channels supported.  The codec
-             * supports any number of channels between 1 and this maximum value.
-             */
-            public final int getMaxInputChannelCount() {
-                return mMaxInputChannelCount;
-            }
-
-            /* no public constructor */
-            private AudioCapabilities() { }
-
-            /** @hide */
-            public static AudioCapabilities create(
-                    MediaFormat info, CodecCapabilities parent) {
-                AudioCapabilities caps = new AudioCapabilities();
-                caps.init(info, parent);
-                return caps;
-            }
-
-            /** @hide */
-            public void init(MediaFormat info, CodecCapabilities parent) {
-                super.init(info, parent);
-                initWithPlatformLimits();
-                applyLevelLimits();
-                parseFromInfo(info);
-            }
-
-            private void initWithPlatformLimits() {
-                mMaxInputChannelCount = MAX_INPUT_CHANNEL_COUNT;
-                // mBitrateRange = Range.create(1, 320000);
-                mSampleRateRanges = new Range[] { Range.create(8000, 96000) };
-                mSampleRates = null;
-            }
-
-            private boolean supports(Integer sampleRate, Integer inputChannels) {
-                // channels and sample rates are checked orthogonally
-                if (inputChannels != null &&
-                        (inputChannels < 1 || inputChannels > mMaxInputChannelCount)) {
-                    return false;
-                }
-                if (sampleRate != null) {
-                    int ix = Utils.binarySearchDistinctRanges(
-                            mSampleRateRanges, sampleRate);
-                    if (ix < 0) {
-                        return false;
-                    }
-                }
-                return true;
-            }
-
-            /**
-             * Query whether the sample rate is supported by the codec.
-             */
-            public final boolean isSampleRateSupported(int sampleRate) {
-                return supports(sampleRate, null);
-            }
-
-            /** modifies rates */
-            private void limitSampleRates(int[] rates) {
-                Arrays.sort(rates);
-                ArrayList<Range<Integer>> ranges = new ArrayList<Range<Integer>>();
-                for (int rate: rates) {
-                    if (supports(rate, null /* channels */)) {
-                        ranges.add(Range.create(rate, rate));
-                    }
-                }
-                mSampleRateRanges = ranges.toArray(new Range[ranges.size()]);
-                createDiscreteSampleRates();
-            }
-
-            private void createDiscreteSampleRates() {
-                mSampleRates = new int[mSampleRateRanges.length];
-                for (int i = 0; i < mSampleRateRanges.length; i++) {
-                    mSampleRates[i] = mSampleRateRanges[i].getLower();
-                }
-            }
-
-            /** modifies rateRanges */
-            private void limitSampleRates(Range<Integer>[] rateRanges) {
-                sortDistinctRanges(rateRanges);
-                mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, rateRanges);
-
-                // check if all values are discrete
-                for (Range<Integer> range: mSampleRateRanges) {
-                    if (!range.getLower().equals(range.getUpper())) {
-                        mSampleRates = null;
-                        return;
-                    }
-                }
-                createDiscreteSampleRates();
-            }
-
-            private void applyLevelLimits() {
-                int[] sampleRates = null;
-                Range<Integer> sampleRateRange = null, bitRates = null;
-                int maxChannels = 0;
-                String mime = mParent.getMime();
-
-                if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MPEG)) {
-                    sampleRates = new int[] {
-                            8000, 11025, 12000,
-                            16000, 22050, 24000,
-                            32000, 44100, 48000 };
-                    bitRates = Range.create(8000, 320000);
-                    maxChannels = 2;
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)) {
-                    sampleRates = new int[] { 8000 };
-                    bitRates = Range.create(4750, 12200);
-                    maxChannels = 1;
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)) {
-                    sampleRates = new int[] { 16000 };
-                    bitRates = Range.create(6600, 23850);
-                    maxChannels = 1;
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) {
-                    sampleRates = new int[] {
-                            7350, 8000,
-                            11025, 12000, 16000,
-                            22050, 24000, 32000,
-                            44100, 48000, 64000,
-                            88200, 96000 };
-                    bitRates = Range.create(8000, 510000);
-                    maxChannels = 48;
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_VORBIS)) {
-                    bitRates = Range.create(32000, 500000);
-                    sampleRates = new int[] { 8000, 12000, 16000, 24000, 48000, 192000 };
-                    maxChannels = 255;
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_OPUS)) {
-                    bitRates = Range.create(6000, 510000);
-                    sampleRates = new int[] { 8000, 12000, 16000, 24000, 48000 };
-                    maxChannels = 255;
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_RAW)) {
-                    sampleRateRange = Range.create(1, 96000);
-                    bitRates = Range.create(1, 10000000);
-                    maxChannels = 8;
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
-                    sampleRateRange = Range.create(1, 655350);
-                    // lossless codec, so bitrate is ignored
-                    maxChannels = 255;
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW)
-                        || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)) {
-                    sampleRates = new int[] { 8000 };
-                    bitRates = Range.create(64000, 64000);
-                    // platform allows multiple channels for this format
-                } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) {
-                    sampleRates = new int[] { 8000 };
-                    bitRates = Range.create(13000, 13000);
-                    maxChannels = 1;
-                } else {
-                    Log.w(TAG, "Unsupported mime " + mime);
-                    mParent.mError |= ERROR_UNSUPPORTED;
-                }
-
-                // restrict ranges
-                if (sampleRates != null) {
-                    limitSampleRates(sampleRates);
-                } else if (sampleRateRange != null) {
-                    limitSampleRates(new Range[] { sampleRateRange });
-                }
-                applyLimits(maxChannels, bitRates);
-            }
-
-            private void applyLimits(int maxInputChannels, Range<Integer> bitRates) {
-                mMaxInputChannelCount = Range.create(1, mMaxInputChannelCount)
-                        .clamp(maxInputChannels);
-                if (bitRates != null) {
-                    mBitrateRange = mBitrateRange.intersect(bitRates);
-                }
-            }
-
-            private void parseFromInfo(MediaFormat info) {
-                int maxInputChannels = MAX_INPUT_CHANNEL_COUNT;
-                Range<Integer> bitRates = POSITIVE_INTEGERS;
-
-                if (info.containsKey("sample-rate-ranges")) {
-                    String[] rateStrings = info.getString("sample-rate-ranges").split(",");
-                    Range<Integer>[] rateRanges = new Range[rateStrings.length];
-                    for (int i = 0; i < rateStrings.length; i++) {
-                        rateRanges[i] = Utils.parseIntRange(rateStrings[i], null);
-                    }
-                    limitSampleRates(rateRanges);
-                }
-                if (info.containsKey("max-channel-count")) {
-                    maxInputChannels = Utils.parseIntSafely(
-                            info.getString("max-channel-count"), maxInputChannels);
-                }
-                if (info.containsKey("bitrate-range")) {
-                    bitRates = bitRates.intersect(
-                            Utils.parseIntRange(info.getString("bitrate"), bitRates));
-                }
-                applyLimits(maxInputChannels, bitRates);
-            }
-
-            /** @hide */
-            public void setDefaultFormat(MediaFormat format) {
-                // report settings that have only a single choice
-                if (mBitrateRange.getLower().equals(mBitrateRange.getUpper())) {
-                    format.setInteger(MediaFormat.KEY_BIT_RATE, mBitrateRange.getLower());
-                }
-                if (mMaxInputChannelCount == 1) {
-                    // mono-only format
-                    format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
-                }
-                if (mSampleRates != null && mSampleRates.length == 1) {
-                    format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRates[0]);
-                }
-            }
-
-            /** @hide */
-            public boolean supportsFormat(MediaFormat format) {
-                Map<String, Object> map = format.getMap();
-                Integer sampleRate = (Integer)map.get(MediaFormat.KEY_SAMPLE_RATE);
-                Integer channels = (Integer)map.get(MediaFormat.KEY_CHANNEL_COUNT);
-                if (!supports(sampleRate, channels)) {
-                    return false;
-                }
-
-                // nothing to do for:
-                // KEY_CHANNEL_MASK: codecs don't get this
-                // KEY_IS_ADTS:      required feature for all AAC decoders
-                return true;
-            }
-        };
-
-        AudioCapabilities mAudioCaps;
-        private boolean isAudio() {
-            return mAudioCaps != null;
+        public Range<Integer> getBitrateRange() {
+            return mBitrateRange;
         }
 
         /**
-         * Returns the audio capabilities or {@code null} if this is not an audio codec.
+         * Returns the array of supported sample rates if the codec
+         * supports only discrete values.  Otherwise, it returns
+         * {@code null}.  The array is sorted in ascending order.
          */
-        public final AudioCapabilities getAudioCapabilities() {
-            return mAudioCaps;
+        public int[] getSupportedSampleRates() {
+            return Arrays.copyOf(mSampleRates, mSampleRates.length);
+        }
+
+        /**
+         * Returns the array of supported sample rate ranges.  The
+         * array is sorted in ascending order, and the ranges are
+         * distinct.
+         */
+        public Range<Integer>[] getSupportedSampleRateRanges() {
+            return Arrays.copyOf(mSampleRateRanges, mSampleRateRanges.length);
+        }
+
+        /**
+         * Returns the maximum number of input channels supported.  The codec
+         * supports any number of channels between 1 and this maximum value.
+         */
+        public int getMaxInputChannelCount() {
+            return mMaxInputChannelCount;
+        }
+
+        /* no public constructor */
+        private AudioCapabilities() { }
+
+        /** @hide */
+        public static AudioCapabilities create(
+                MediaFormat info, CodecCapabilities parent) {
+            AudioCapabilities caps = new AudioCapabilities();
+            caps.init(info, parent);
+            return caps;
         }
 
         /** @hide */
-        public CodecCapabilities dup() {
-            return new CodecCapabilities(
-                // clone writable arrays
-                Arrays.copyOf(profileLevels, profileLevels.length),
-                Arrays.copyOf(colorFormats, colorFormats.length),
-                isEncoder(),
-                mFlagsVerified,
-                mDefaultFormat,
-                mCapabilitiesInfo);
+        public void init(MediaFormat info, CodecCapabilities parent) {
+            mParent = parent;
+            initWithPlatformLimits();
+            applyLevelLimits();
+            parseFromInfo(info);
+        }
+
+        private void initWithPlatformLimits() {
+            mBitrateRange = Range.create(0, Integer.MAX_VALUE);
+            mMaxInputChannelCount = MAX_INPUT_CHANNEL_COUNT;
+            // mBitrateRange = Range.create(1, 320000);
+            mSampleRateRanges = new Range[] { Range.create(8000, 96000) };
+            mSampleRates = null;
+        }
+
+        private boolean supports(Integer sampleRate, Integer inputChannels) {
+            // channels and sample rates are checked orthogonally
+            if (inputChannels != null &&
+                    (inputChannels < 1 || inputChannels > mMaxInputChannelCount)) {
+                return false;
+            }
+            if (sampleRate != null) {
+                int ix = Utils.binarySearchDistinctRanges(
+                        mSampleRateRanges, sampleRate);
+                if (ix < 0) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Query whether the sample rate is supported by the codec.
+         */
+        public boolean isSampleRateSupported(int sampleRate) {
+            return supports(sampleRate, null);
+        }
+
+        /** modifies rates */
+        private void limitSampleRates(int[] rates) {
+            Arrays.sort(rates);
+            ArrayList<Range<Integer>> ranges = new ArrayList<Range<Integer>>();
+            for (int rate: rates) {
+                if (supports(rate, null /* channels */)) {
+                    ranges.add(Range.create(rate, rate));
+                }
+            }
+            mSampleRateRanges = ranges.toArray(new Range[ranges.size()]);
+            createDiscreteSampleRates();
+        }
+
+        private void createDiscreteSampleRates() {
+            mSampleRates = new int[mSampleRateRanges.length];
+            for (int i = 0; i < mSampleRateRanges.length; i++) {
+                mSampleRates[i] = mSampleRateRanges[i].getLower();
+            }
+        }
+
+        /** modifies rateRanges */
+        private void limitSampleRates(Range<Integer>[] rateRanges) {
+            sortDistinctRanges(rateRanges);
+            mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, rateRanges);
+
+            // check if all values are discrete
+            for (Range<Integer> range: mSampleRateRanges) {
+                if (!range.getLower().equals(range.getUpper())) {
+                    mSampleRates = null;
+                    return;
+                }
+            }
+            createDiscreteSampleRates();
+        }
+
+        private void applyLevelLimits() {
+            int[] sampleRates = null;
+            Range<Integer> sampleRateRange = null, bitRates = null;
+            int maxChannels = 0;
+            String mime = mParent.getMimeType();
+
+            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MPEG)) {
+                sampleRates = new int[] {
+                        8000, 11025, 12000,
+                        16000, 22050, 24000,
+                        32000, 44100, 48000 };
+                bitRates = Range.create(8000, 320000);
+                maxChannels = 2;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)) {
+                sampleRates = new int[] { 8000 };
+                bitRates = Range.create(4750, 12200);
+                maxChannels = 1;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)) {
+                sampleRates = new int[] { 16000 };
+                bitRates = Range.create(6600, 23850);
+                maxChannels = 1;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) {
+                sampleRates = new int[] {
+                        7350, 8000,
+                        11025, 12000, 16000,
+                        22050, 24000, 32000,
+                        44100, 48000, 64000,
+                        88200, 96000 };
+                bitRates = Range.create(8000, 510000);
+                maxChannels = 48;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_VORBIS)) {
+                bitRates = Range.create(32000, 500000);
+                sampleRates = new int[] { 8000, 12000, 16000, 24000, 48000, 192000 };
+                maxChannels = 255;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_OPUS)) {
+                bitRates = Range.create(6000, 510000);
+                sampleRates = new int[] { 8000, 12000, 16000, 24000, 48000 };
+                maxChannels = 255;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_RAW)) {
+                sampleRateRange = Range.create(1, 96000);
+                bitRates = Range.create(1, 10000000);
+                maxChannels = 8;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
+                sampleRateRange = Range.create(1, 655350);
+                // lossless codec, so bitrate is ignored
+                maxChannels = 255;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)) {
+                sampleRates = new int[] { 8000 };
+                bitRates = Range.create(64000, 64000);
+                // platform allows multiple channels for this format
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) {
+                sampleRates = new int[] { 8000 };
+                bitRates = Range.create(13000, 13000);
+                maxChannels = 1;
+            } else {
+                Log.w(TAG, "Unsupported mime " + mime);
+                mParent.mError |= ERROR_UNSUPPORTED;
+            }
+
+            // restrict ranges
+            if (sampleRates != null) {
+                limitSampleRates(sampleRates);
+            } else if (sampleRateRange != null) {
+                limitSampleRates(new Range[] { sampleRateRange });
+            }
+            applyLimits(maxChannels, bitRates);
+        }
+
+        private void applyLimits(int maxInputChannels, Range<Integer> bitRates) {
+            mMaxInputChannelCount = Range.create(1, mMaxInputChannelCount)
+                    .clamp(maxInputChannels);
+            if (bitRates != null) {
+                mBitrateRange = mBitrateRange.intersect(bitRates);
+            }
+        }
+
+        private void parseFromInfo(MediaFormat info) {
+            int maxInputChannels = MAX_INPUT_CHANNEL_COUNT;
+            Range<Integer> bitRates = POSITIVE_INTEGERS;
+
+            if (info.containsKey("sample-rate-ranges")) {
+                String[] rateStrings = info.getString("sample-rate-ranges").split(",");
+                Range<Integer>[] rateRanges = new Range[rateStrings.length];
+                for (int i = 0; i < rateStrings.length; i++) {
+                    rateRanges[i] = Utils.parseIntRange(rateStrings[i], null);
+                }
+                limitSampleRates(rateRanges);
+            }
+            if (info.containsKey("max-channel-count")) {
+                maxInputChannels = Utils.parseIntSafely(
+                        info.getString("max-channel-count"), maxInputChannels);
+            }
+            if (info.containsKey("bitrate-range")) {
+                bitRates = bitRates.intersect(
+                        Utils.parseIntRange(info.getString("bitrate"), bitRates));
+            }
+            applyLimits(maxInputChannels, bitRates);
+        }
+
+        /** @hide */
+        public void setDefaultFormat(MediaFormat format) {
+            // report settings that have only a single choice
+            if (mBitrateRange.getLower().equals(mBitrateRange.getUpper())) {
+                format.setInteger(MediaFormat.KEY_BIT_RATE, mBitrateRange.getLower());
+            }
+            if (mMaxInputChannelCount == 1) {
+                // mono-only format
+                format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
+            }
+            if (mSampleRates != null && mSampleRates.length == 1) {
+                format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRates[0]);
+            }
+        }
+
+        /** @hide */
+        public boolean supportsFormat(MediaFormat format) {
+            Map<String, Object> map = format.getMap();
+            Integer sampleRate = (Integer)map.get(MediaFormat.KEY_SAMPLE_RATE);
+            Integer channels = (Integer)map.get(MediaFormat.KEY_CHANNEL_COUNT);
+            if (!supports(sampleRate, channels)) {
+                return false;
+            }
+
+            // nothing to do for:
+            // KEY_CHANNEL_MASK: codecs don't get this
+            // KEY_IS_ADTS:      required feature for all AAC decoders
+            return true;
+        }
+    }
+
+    /**
+     * A class that supports querying the video capabilities of a codec.
+     */
+    public static final class VideoCapabilities {
+        private static final String TAG = "VideoCapabilities";
+        private CodecCapabilities mParent;
+        private Range<Integer> mBitrateRange;
+
+        private Range<Integer> mHeightRange;
+        private Range<Integer> mWidthRange;
+        private Range<Integer> mBlockCountRange;
+        private Range<Integer> mHorizontalBlockRange;
+        private Range<Integer> mVerticalBlockRange;
+        private Range<Rational> mAspectRatioRange;
+        private Range<Rational> mBlockAspectRatioRange;
+        private Range<Long> mBlocksPerSecondRange;
+        private Range<Integer> mFrameRateRange;
+
+        private int mBlockWidth;
+        private int mBlockHeight;
+        private int mWidthAlignment;
+        private int mHeightAlignment;
+        private int mSmallerDimensionUpperLimit;
+
+        /**
+         * Returns the range of supported bitrates in bits/second.
+         */
+        public Range<Integer> getBitrateRange() {
+            return mBitrateRange;
+        }
+
+        /**
+         * Returns the range of supported video widths.
+         */
+        public Range<Integer> getSupportedWidths() {
+            return mWidthRange;
+        }
+
+        /**
+         * Returns the range of supported video heights.
+         */
+        public Range<Integer> getSupportedHeights() {
+            return mHeightRange;
+        }
+
+        /**
+         * Returns the alignment requirement for video width (in pixels).
+         *
+         * This is a power-of-2 value that video width must be a
+         * multiple of.
+         */
+        public int getWidthAlignment() {
+            return mWidthAlignment;
+        }
+
+        /**
+         * Returns the alignment requirement for video height (in pixels).
+         *
+         * This is a power-of-2 value that video height must be a
+         * multiple of.
+         */
+        public int getHeightAlignment() {
+            return mHeightAlignment;
+        }
+
+        /**
+         * Return the upper limit on the smaller dimension of width or height.
+         * <p></p>
+         * 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())}.
+         *
+         * @hide
+         */
+        public int getSmallerDimensionUpperLimit() {
+            return mSmallerDimensionUpperLimit;
+        }
+
+        /**
+         * Returns the range of supported frame rates.
+         * <p>
+         * 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.
+         */
+        public Range<Integer> getSupportedFrameRates() {
+            return mFrameRateRange;
+        }
+
+        /**
+         * Returns the range of supported video widths for a video height.
+         * @param height the height of the video
+         */
+        public Range<Integer> getSupportedWidthsFor(int height) {
+            try {
+                Range<Integer> range = mWidthRange;
+                if (!mHeightRange.contains(height)
+                        || (height % mHeightAlignment) != 0) {
+                    throw new IllegalArgumentException("unsupported height");
+                }
+                final int heightInBlocks = Utils.divUp(height, mBlockHeight);
+
+                // constrain by block count and by block aspect ratio
+                final int minWidthInBlocks = Math.max(
+                        Utils.divUp(mBlockCountRange.getLower(), heightInBlocks),
+                        (int)Math.ceil(mBlockAspectRatioRange.getLower().doubleValue()
+                                * heightInBlocks));
+                final int maxWidthInBlocks = Math.min(
+                        mBlockCountRange.getUpper() / heightInBlocks,
+                        (int)(mBlockAspectRatioRange.getUpper().doubleValue()
+                                * 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(
+                        (int)Math.ceil(mAspectRatioRange.getLower().doubleValue()
+                                * height),
+                        (int)(mAspectRatioRange.getUpper().doubleValue() * height));
+                return range;
+            } catch (IllegalArgumentException e) {
+                // should not be here
+                Log.w(TAG, "could not get supported widths for " + height , e);
+                throw new IllegalArgumentException("unsupported height");
+            }
+        }
+
+        /**
+         * Returns the range of supported video heights for a video width
+         * @param width the width of the video
+         */
+        public Range<Integer> getSupportedHeightsFor(int width) {
+            try {
+                Range<Integer> range = mHeightRange;
+                if (!mWidthRange.contains(width)
+                        || (width % mWidthAlignment) != 0) {
+                    throw new IllegalArgumentException("unsupported width");
+                }
+                final int widthInBlocks = Utils.divUp(width, mBlockWidth);
+
+                // constrain by block count and by block aspect ratio
+                final int minHeightInBlocks = Math.max(
+                        Utils.divUp(mBlockCountRange.getLower(), widthInBlocks),
+                        (int)Math.ceil(widthInBlocks /
+                                mBlockAspectRatioRange.getUpper().doubleValue()));
+                final int maxHeightInBlocks = Math.min(
+                        mBlockCountRange.getUpper() / widthInBlocks,
+                        (int)(widthInBlocks /
+                                mBlockAspectRatioRange.getLower().doubleValue()));
+                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(
+                        (int)Math.ceil(width /
+                                mAspectRatioRange.getUpper().doubleValue()),
+                        (int)(width / mAspectRatioRange.getLower().doubleValue()));
+                return range;
+            } catch (IllegalArgumentException e) {
+                // should not be here
+                Log.w(TAG, "could not get supported heights for " + width , e);
+                throw new IllegalArgumentException("unsupported width");
+            }
+        }
+
+        /**
+         * Returns the range of supported video frame rates for a video size.
+         * <p>
+         * 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
+         */
+        public Range<Double> getSupportedFrameRatesFor(int width, int height) {
+            Range<Integer> range = mHeightRange;
+            if (!supports(width, height, null)) {
+                throw new IllegalArgumentException("unsupported size");
+            }
+            final int blockCount =
+                Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight);
+
+            return Range.create(
+                    Math.max(mBlocksPerSecondRange.getLower() / (double) blockCount,
+                            (double) mFrameRateRange.getLower()),
+                    Math.min(mBlocksPerSecondRange.getUpper() / (double) blockCount,
+                            (double) mFrameRateRange.getUpper()));
+        }
+
+        /**
+         * Returns whether a given video size ({@code width} and
+         * {@code height}) and {@code frameRate} combination is supported.
+         */
+        public boolean areSizeAndRateSupported(
+                int width, int height, double frameRate) {
+            return supports(width, height, frameRate);
+        }
+
+        /**
+         * Returns whether a given video size ({@code width} and
+         * {@code height}) is supported.
+         */
+        public boolean isSizeSupported(int width, int height) {
+            return supports(width, height, null);
+        }
+
+        private boolean supports(
+                Integer width, Integer height, Double rate) {
+            boolean ok = true;
+
+            if (ok && width != null) {
+                ok = mWidthRange.contains(width)
+                        && (width % mWidthAlignment == 0);
+            }
+            if (ok && height != null) {
+                ok = mHeightRange.contains(height)
+                        && (height % mHeightAlignment == 0);
+            }
+            if (ok && rate != null) {
+                ok = mFrameRateRange.contains(Utils.intRangeFor(rate));
+            }
+            if (ok && height != null && width != null) {
+                ok = Math.min(height, width) <= mSmallerDimensionUpperLimit;
+
+                final int widthInBlocks = Utils.divUp(width, mBlockWidth);
+                final int heightInBlocks = Utils.divUp(height, mBlockHeight);
+                final int blockCount = widthInBlocks * heightInBlocks;
+                ok = ok && mBlockCountRange.contains(blockCount)
+                        && mBlockAspectRatioRange.contains(
+                                new Rational(widthInBlocks, heightInBlocks))
+                        && mAspectRatioRange.contains(new Rational(width, height));
+                if (ok && rate != null) {
+                    double blocksPerSec = blockCount * rate;
+                    ok = mBlocksPerSecondRange.contains(
+                            Utils.longRangeFor(blocksPerSec));
+                }
+            }
+            return ok;
+        }
+
+        /**
+         * @hide
+         * @throws java.lang.ClassCastException */
+        public boolean supportsFormat(MediaFormat format) {
+            final Map<String, Object> map = format.getMap();
+            Integer width = (Integer)map.get(MediaFormat.KEY_WIDTH);
+            Integer height = (Integer)map.get(MediaFormat.KEY_HEIGHT);
+            Double rate = (Double)map.get(MediaFormat.KEY_FRAME_RATE);
+
+            // we ignore color-format for now as it is not reliably reported by codec
+
+            return supports(width, height, rate);
+        }
+
+        /* no public constructor */
+        private VideoCapabilities() { }
+
+        /** @hide */
+        public static VideoCapabilities create(
+                MediaFormat info, CodecCapabilities parent) {
+            VideoCapabilities caps = new VideoCapabilities();
+            caps.init(info, parent);
+            return caps;
+        }
+
+        /** @hide */
+        public void init(MediaFormat info, CodecCapabilities parent) {
+            mParent = parent;
+            initWithPlatformLimits();
+            applyLevelLimits();
+            parseFromInfo(info);
+            updateLimits();
+        }
+
+        /** @hide */
+        public Size getBlockSize() {
+            return new Size(mBlockWidth, mBlockHeight);
+        }
+
+        /** @hide */
+        public Range<Integer> getBlockCountRange() {
+            return mBlockCountRange;
+        }
+
+        /** @hide */
+        public Range<Long> getBlocksPerSecondRange() {
+            return mBlocksPerSecondRange;
+        }
+
+        /** @hide */
+        public Range<Rational> getAspectRatioRange(boolean blocks) {
+            return blocks ? mBlockAspectRatioRange : mAspectRatioRange;
+        }
+
+        private void initWithPlatformLimits() {
+            mBitrateRange = Range.create(0, Integer.MAX_VALUE);
+
+            mWidthRange  = SIZE_RANGE;
+            mHeightRange = SIZE_RANGE;
+            mFrameRateRange = FRAME_RATE_RANGE;
+
+            mHorizontalBlockRange = SIZE_RANGE;
+            mVerticalBlockRange   = SIZE_RANGE;
+
+            // full positive ranges are supported as these get calculated
+            mBlockCountRange      = POSITIVE_INTEGERS;
+            mBlocksPerSecondRange = POSITIVE_LONGS;
+
+            mBlockAspectRatioRange = POSITIVE_RATIONALS;
+            mAspectRatioRange      = POSITIVE_RATIONALS;
+
+            // YUV 4:2:0 requires 2:2 alignment
+            mWidthAlignment = 2;
+            mHeightAlignment = 2;
+            mBlockWidth = 2;
+            mBlockHeight = 2;
+            mSmallerDimensionUpperLimit = SIZE_RANGE.getUpper();
+        }
+
+        private void parseFromInfo(MediaFormat info) {
+            final Map<String, Object> map = info.getMap();
+            Size blockSize = new Size(mBlockWidth, mBlockHeight);
+            Size alignment = new Size(mWidthAlignment, mHeightAlignment);
+            Range<Integer> counts = null, widths = null, heights = null;
+            Range<Integer> frameRates = null;
+            Range<Long> blockRates = null;
+            Range<Rational> ratios = null, blockRatios = null;
+
+            blockSize = Utils.parseSize(map.get("block-size"), blockSize);
+            alignment = Utils.parseSize(map.get("alignment"), alignment);
+            counts = Utils.parseIntRange(map.get("block-count-range"), null);
+            blockRates =
+                Utils.parseLongRange(map.get("blocks-per-second-range"), null);
+            {
+                Object o = map.get("size-range");
+                Pair<Size, Size> sizeRange = Utils.parseSizeRange(o);
+                if (sizeRange != null) {
+                    try {
+                        widths = Range.create(
+                                sizeRange.first.getWidth(),
+                                sizeRange.second.getWidth());
+                        heights = Range.create(
+                                sizeRange.first.getHeight(),
+                                sizeRange.second.getHeight());
+                    } catch (IllegalArgumentException e) {
+                        Log.w(TAG, "could not parse size range '" + o + "'");
+                        widths = null;
+                        heights = null;
+                    }
+                }
+            }
+            // 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 (Integer.valueOf(1).equals(map.get("feature-can-swap-width-height"))) {
+                if (widths != null) {
+                    mSmallerDimensionUpperLimit =
+                        Math.min(widths.getUpper(), heights.getUpper());
+                    widths = heights = widths.extend(heights);
+                } else {
+                    Log.w(TAG, "feature can-swap-width-height is best used with size-range");
+                    mSmallerDimensionUpperLimit =
+                        Math.min(mWidthRange.getUpper(), mHeightRange.getUpper());
+                    mWidthRange = mHeightRange = mWidthRange.extend(mHeightRange);
+                }
+            }
+
+            ratios = Utils.parseRationalRange(
+                    map.get("block-aspect-ratio-range"), null);
+            blockRatios = Utils.parseRationalRange(
+                    map.get("pixel-aspect-ratio-range"), null);
+            frameRates = Utils.parseIntRange(map.get("frame-rate-range"), null);
+            if (frameRates != null) {
+                try {
+                    frameRates = frameRates.intersect(FRAME_RATE_RANGE);
+                } catch (IllegalArgumentException e) {
+                    Log.w(TAG, "frame rate range (" + frameRates
+                            + ") is out of limits: " + FRAME_RATE_RANGE);
+                    frameRates = null;
+                }
+            }
+
+            checkPowerOfTwo(
+                    blockSize.getWidth(), "block-size width must be power of two");
+            checkPowerOfTwo(
+                    blockSize.getHeight(), "block-size height must be power of two");
+
+            checkPowerOfTwo(
+                    alignment.getWidth(), "alignment width must be power of two");
+            checkPowerOfTwo(
+                    alignment.getHeight(), "alignment height must be power of two");
+
+            // update block-size and alignment
+            applyMacroBlockLimits(
+                    Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,
+                    Long.MAX_VALUE, blockSize.getWidth(), blockSize.getHeight(),
+                    alignment.getWidth(), alignment.getHeight());
+
+            if ((mParent.mError & ERROR_UNSUPPORTED) != 0) {
+                // codec supports profiles that we don't know.
+                // Use supplied values clipped to platform limits
+                if (widths != null) {
+                    mWidthRange = SIZE_RANGE.intersect(widths);
+                }
+                if (heights != null) {
+                    mHeightRange = SIZE_RANGE.intersect(heights);
+                }
+                if (counts != null) {
+                    mBlockCountRange = POSITIVE_INTEGERS.intersect(
+                            Utils.factorRange(counts, mBlockWidth * mBlockHeight
+                                    / blockSize.getWidth() / blockSize.getHeight()));
+                }
+                if (blockRates != null) {
+                    mBlocksPerSecondRange = POSITIVE_LONGS.intersect(
+                            Utils.factorRange(blockRates, mBlockWidth * mBlockHeight
+                                    / blockSize.getWidth() / blockSize.getHeight()));
+                }
+                if (blockRatios != null) {
+                    mBlockAspectRatioRange = POSITIVE_RATIONALS.intersect(
+                            Utils.scaleRange(blockRatios,
+                                    mBlockHeight / blockSize.getHeight(),
+                                    mBlockWidth / blockSize.getWidth()));
+                }
+                if (ratios != null) {
+                    mAspectRatioRange = POSITIVE_RATIONALS.intersect(ratios);
+                }
+                if (frameRates != null) {
+                    mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates);
+                }
+            } else {
+                // no unsupported profile/levels, so restrict values to known limits
+                if (widths != null) {
+                    mWidthRange = mWidthRange.intersect(widths);
+                }
+                if (heights != null) {
+                    mHeightRange = mHeightRange.intersect(heights);
+                }
+                if (counts != null) {
+                    mBlockCountRange = mBlockCountRange.intersect(
+                            Utils.factorRange(counts, mBlockWidth * mBlockHeight
+                                    / blockSize.getWidth() / blockSize.getHeight()));
+                }
+                if (blockRates != null) {
+                    mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
+                            Utils.factorRange(blockRates, mBlockWidth * mBlockHeight
+                                    / blockSize.getWidth() / blockSize.getHeight()));
+                }
+                if (blockRatios != null) {
+                    mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
+                            Utils.scaleRange(blockRatios,
+                                    mBlockHeight / blockSize.getHeight(),
+                                    mBlockWidth / blockSize.getWidth()));
+                }
+                if (ratios != null) {
+                    mAspectRatioRange = mAspectRatioRange.intersect(ratios);
+                }
+                if (frameRates != null) {
+                    mFrameRateRange = mFrameRateRange.intersect(frameRates);
+                }
+            }
+            updateLimits();
+        }
+
+        private void applyBlockLimits(
+                int blockWidth, int blockHeight,
+                Range<Integer> counts, Range<Long> rates, Range<Rational> ratios) {
+            checkPowerOfTwo(blockWidth, "blockWidth must be a power of two");
+            checkPowerOfTwo(blockHeight, "blockHeight must be a power of two");
+
+            final int newBlockWidth = Math.max(blockWidth, mBlockWidth);
+            final int newBlockHeight = Math.max(blockHeight, mBlockHeight);
+
+            // factor will always be a power-of-2
+            int factor =
+                newBlockWidth * newBlockHeight / mBlockWidth / mBlockHeight;
+            if (factor != 1) {
+                mBlockCountRange = Utils.factorRange(mBlockCountRange, factor);
+                mBlocksPerSecondRange = Utils.factorRange(
+                        mBlocksPerSecondRange, factor);
+                mBlockAspectRatioRange = Utils.scaleRange(
+                        mBlockAspectRatioRange,
+                        newBlockHeight / mBlockHeight,
+                        newBlockWidth / mBlockWidth);
+                mHorizontalBlockRange = Utils.factorRange(
+                        mHorizontalBlockRange, newBlockWidth / mBlockWidth);
+                mVerticalBlockRange = Utils.factorRange(
+                        mVerticalBlockRange, newBlockHeight / mBlockHeight);
+            }
+            factor = newBlockWidth * newBlockHeight / blockWidth / blockHeight;
+            if (factor != 1) {
+                counts = Utils.factorRange(counts, factor);
+                rates = Utils.factorRange(rates, factor);
+                ratios = Utils.scaleRange(
+                        ratios, newBlockHeight / blockHeight,
+                        newBlockWidth / blockWidth);
+            }
+            mBlockCountRange = mBlockCountRange.intersect(counts);
+            mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(rates);
+            mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(ratios);
+            mBlockWidth = newBlockWidth;
+            mBlockHeight = newBlockHeight;
+        }
+
+        private void applyAlignment(int widthAlignment, int heightAlignment) {
+            checkPowerOfTwo(widthAlignment, "widthAlignment must be a power of two");
+            checkPowerOfTwo(heightAlignment, "heightAlignment must be a power of two");
+
+            if (widthAlignment > mBlockWidth || heightAlignment > mBlockHeight) {
+                // maintain assumption that 0 < alignment <= block-size
+                applyBlockLimits(
+                        Math.max(widthAlignment, mBlockWidth),
+                        Math.max(heightAlignment, mBlockHeight),
+                        POSITIVE_INTEGERS, POSITIVE_LONGS, POSITIVE_RATIONALS);
+            }
+
+            mWidthAlignment = Math.max(widthAlignment, mWidthAlignment);
+            mHeightAlignment = Math.max(heightAlignment, mHeightAlignment);
+
+            mWidthRange = Utils.alignRange(mWidthRange, mWidthAlignment);
+            mHeightRange = Utils.alignRange(mHeightRange, mHeightAlignment);
+        }
+
+        private void updateLimits() {
+            // pixels -> blocks <- counts
+            mHorizontalBlockRange = mHorizontalBlockRange.intersect(
+                    Utils.factorRange(mWidthRange, mBlockWidth));
+            mHorizontalBlockRange = mHorizontalBlockRange.intersect(
+                    Range.create(
+                            mBlockCountRange.getLower() / mVerticalBlockRange.getUpper(),
+                            mBlockCountRange.getUpper() / mVerticalBlockRange.getLower()));
+            mVerticalBlockRange = mVerticalBlockRange.intersect(
+                    Utils.factorRange(mHeightRange, mBlockHeight));
+            mVerticalBlockRange = mVerticalBlockRange.intersect(
+                    Range.create(
+                            mBlockCountRange.getLower() / mHorizontalBlockRange.getUpper(),
+                            mBlockCountRange.getUpper() / mHorizontalBlockRange.getLower()));
+            mBlockCountRange = mBlockCountRange.intersect(
+                    Range.create(
+                            mHorizontalBlockRange.getLower()
+                                    * mVerticalBlockRange.getLower(),
+                            mHorizontalBlockRange.getUpper()
+                                    * mVerticalBlockRange.getUpper()));
+            mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
+                    new Rational(
+                            mHorizontalBlockRange.getLower(), mVerticalBlockRange.getUpper()),
+                    new Rational(
+                            mHorizontalBlockRange.getUpper(), mVerticalBlockRange.getLower()));
+
+            // blocks -> pixels
+            mWidthRange = mWidthRange.intersect(
+                    (mHorizontalBlockRange.getLower() - 1) * mBlockWidth + mWidthAlignment,
+                    mHorizontalBlockRange.getUpper() * mBlockWidth);
+            mHeightRange = mHeightRange.intersect(
+                    (mVerticalBlockRange.getLower() - 1) * mBlockHeight + mHeightAlignment,
+                    mVerticalBlockRange.getUpper() * mBlockHeight);
+            mAspectRatioRange = mAspectRatioRange.intersect(
+                    new Rational(mWidthRange.getLower(), mHeightRange.getUpper()),
+                    new Rational(mWidthRange.getUpper(), mHeightRange.getLower()));
+
+            mSmallerDimensionUpperLimit = Math.min(
+                    mSmallerDimensionUpperLimit,
+                    Math.min(mWidthRange.getUpper(), mHeightRange.getUpper()));
+
+            // blocks -> rate
+            mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
+                    mBlockCountRange.getLower() * (long)mFrameRateRange.getLower(),
+                    mBlockCountRange.getUpper() * (long)mFrameRateRange.getUpper());
+            mFrameRateRange = mFrameRateRange.intersect(
+                    (int)(mBlocksPerSecondRange.getLower()
+                            / mBlockCountRange.getUpper()),
+                    (int)(mBlocksPerSecondRange.getUpper()
+                            / (double)mBlockCountRange.getLower()));
+        }
+
+        private void applyMacroBlockLimits(
+                int maxHorizontalBlocks, int maxVerticalBlocks,
+                int maxBlocks, long maxBlocksPerSecond,
+                int blockWidth, int blockHeight,
+                int widthAlignment, int heightAlignment) {
+            applyAlignment(widthAlignment, heightAlignment);
+            applyBlockLimits(
+                    blockWidth, blockHeight, Range.create(1, maxBlocks),
+                    Range.create(1L, maxBlocksPerSecond),
+                    Range.create(
+                            new Rational(1, maxVerticalBlocks),
+                            new Rational(maxHorizontalBlocks, 1)));
+            mHorizontalBlockRange =
+                    mHorizontalBlockRange.intersect(
+                            1, maxHorizontalBlocks / (mBlockWidth / blockWidth));
+            mVerticalBlockRange =
+                    mVerticalBlockRange.intersect(
+                            1, maxVerticalBlocks / (mBlockHeight / blockHeight));
+        }
+
+        private void applyLevelLimits() {
+            int maxBlocksPerSecond = 0;
+            int maxBlocks = 0;
+            int maxBps = 0;
+            int maxDPBBlocks = 0;
+
+            int errors = ERROR_NONE_SUPPORTED;
+            CodecProfileLevel[] profileLevels = mParent.profileLevels;
+            String mime = mParent.getMimeType();
+
+            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+                maxBlocks = 99;
+                maxBlocksPerSecond = 1485;
+                maxBps = 64000;
+                maxDPBBlocks = 396;
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    int MBPS = 0, FS = 0, BR = 0, DPB = 0;
+                    boolean supported = true;
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.AVCLevel1:
+                            MBPS =    1485; FS =    99; BR =     64; DPB =    396; break;
+                        case CodecProfileLevel.AVCLevel1b:
+                            MBPS =    1485; FS =    99; BR =    128; DPB =    396; break;
+                        case CodecProfileLevel.AVCLevel11:
+                            MBPS =    3000; FS =   396; BR =    192; DPB =    900; break;
+                        case CodecProfileLevel.AVCLevel12:
+                            MBPS =    6000; FS =   396; BR =    384; DPB =   2376; break;
+                        case CodecProfileLevel.AVCLevel13:
+                            MBPS =   11880; FS =   396; BR =    768; DPB =   2376; break;
+                        case CodecProfileLevel.AVCLevel2:
+                            MBPS =   11880; FS =   396; BR =   2000; DPB =   2376; break;
+                        case CodecProfileLevel.AVCLevel21:
+                            MBPS =   19800; FS =   792; BR =   4000; DPB =   4752; break;
+                        case CodecProfileLevel.AVCLevel22:
+                            MBPS =   20250; FS =  1620; BR =   4000; DPB =   8100; break;
+                        case CodecProfileLevel.AVCLevel3:
+                            MBPS =   40500; FS =  1620; BR =  10000; DPB =   8100; break;
+                        case CodecProfileLevel.AVCLevel31:
+                            MBPS =  108000; FS =  3600; BR =  14000; DPB =  18000; break;
+                        case CodecProfileLevel.AVCLevel32:
+                            MBPS =  216000; FS =  5120; BR =  20000; DPB =  20480; break;
+                        case CodecProfileLevel.AVCLevel4:
+                            MBPS =  245760; FS =  8192; BR =  20000; DPB =  32768; break;
+                        case CodecProfileLevel.AVCLevel41:
+                            MBPS =  245760; FS =  8192; BR =  50000; DPB =  32768; break;
+                        case CodecProfileLevel.AVCLevel42:
+                            MBPS =  522240; FS =  8704; BR =  50000; DPB =  34816; break;
+                        case CodecProfileLevel.AVCLevel5:
+                            MBPS =  589824; FS = 22080; BR = 135000; DPB = 110400; break;
+                        case CodecProfileLevel.AVCLevel51:
+                            MBPS =  983040; FS = 36864; BR = 240000; DPB = 184320; break;
+                        case CodecProfileLevel.AVCLevel52:
+                            MBPS = 2073600; FS = 36864; BR = 240000; DPB = 184320; break;
+                        default:
+                            Log.w(TAG, "Unrecognized level "
+                                    + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.AVCProfileHigh:
+                            BR *= 1250; break;
+                        case CodecProfileLevel.AVCProfileHigh10:
+                            BR *= 3000; break;
+                        case CodecProfileLevel.AVCProfileExtended:
+                        case CodecProfileLevel.AVCProfileHigh422:
+                        case CodecProfileLevel.AVCProfileHigh444:
+                            Log.w(TAG, "Unsupported profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNSUPPORTED;
+                            supported = false;
+                            // fall through - treat as base profile
+                        case CodecProfileLevel.AVCProfileBaseline:
+                        case CodecProfileLevel.AVCProfileMain:
+                            BR *= 1000; break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                            BR *= 1000;
+                    }
+                    if (supported) {
+                        errors &= ~ERROR_NONE_SUPPORTED;
+                    }
+                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR, maxBps);
+                    maxDPBBlocks = Math.max(maxDPBBlocks, DPB);
+                }
+
+                int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8));
+                applyMacroBlockLimits(
+                        maxLengthInBlocks, maxLengthInBlocks,
+                        maxBlocks, maxBlocksPerSecond,
+                        16 /* blockWidth */, 16 /* blockHeight */,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
+                int maxWidth = 11, maxHeight = 9, maxRate = 15;
+                maxBlocks = 99;
+                maxBlocksPerSecond = 1485;
+                maxBps = 64000;
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0;
+                    boolean supported = true;
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.MPEG4ProfileSimple:
+                            switch (profileLevel.level) {
+                                case CodecProfileLevel.MPEG4Level0:
+                                    FR = 15; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
+                                case CodecProfileLevel.MPEG4Level1:
+                                    FR = 30; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
+                                case CodecProfileLevel.MPEG4Level0b:
+                                    FR = 30; W = 11; H =  9; MBPS =  1485; FS =  99; BR = 128; break;
+                                case CodecProfileLevel.MPEG4Level2:
+                                    FR = 30; W = 22; H = 18; MBPS =  5940; FS = 396; BR = 128; break;
+                                case CodecProfileLevel.MPEG4Level3:
+                                    FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384; break;
+                                case CodecProfileLevel.MPEG4Level4:
+                                case CodecProfileLevel.MPEG4Level4a:
+                                case CodecProfileLevel.MPEG4Level5:
+                                    // While MPEG4 SP does not have level 4 or 5, some vendors
+                                    // report it. Use the same limits as level 3, but mark as
+                                    // unsupported.
+                                    FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384;
+                                    supported = false;
+                                    break;
+                                default:
+                                    Log.w(TAG, "Unrecognized profile/level "
+                                            + profileLevel.profile + "/"
+                                            + profileLevel.level + " for " + mime);
+                                    errors |= ERROR_UNRECOGNIZED;
+                            }
+                            break;
+                        case CodecProfileLevel.MPEG4ProfileAdvancedSimple:
+                            switch (profileLevel.level) {
+                                case CodecProfileLevel.MPEG4Level0:
+                                case CodecProfileLevel.MPEG4Level1:
+                                    FR = 30; W = 11; H =  9; MBPS =  2970; FS =   99; BR =  128; break;
+                                case CodecProfileLevel.MPEG4Level2:
+                                    FR = 30; W = 22; H = 18; MBPS =  5940; FS =  396; BR =  384; break;
+                                case CodecProfileLevel.MPEG4Level3:
+                                    FR = 30; W = 22; H = 18; MBPS = 11880; FS =  396; BR =  768; break;
+                                // case CodecProfileLevel.MPEG4Level3b:
+                                // TODO: MPEG4 level 3b is not defined in OMX
+                                //  MBPS = 11880; FS =  396; BR = 1500; break;
+                                case CodecProfileLevel.MPEG4Level4:
+                                case CodecProfileLevel.MPEG4Level4a:
+                                    // TODO: MPEG4 level 4a is not defined in spec
+                                    FR = 30; W = 44; H = 36; MBPS = 23760; FS =  792; BR = 3000; break;
+                                case CodecProfileLevel.MPEG4Level5:
+                                    FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 8000; break;
+                                default:
+                                    Log.w(TAG, "Unrecognized profile/level "
+                                            + profileLevel.profile + "/"
+                                            + profileLevel.level + " for " + mime);
+                                    errors |= ERROR_UNRECOGNIZED;
+                            }
+                            break;
+                        case CodecProfileLevel.MPEG4ProfileMain:             // 2-4
+                        case CodecProfileLevel.MPEG4ProfileNbit:             // 2
+                        case CodecProfileLevel.MPEG4ProfileAdvancedRealTime: // 1-4
+                        case CodecProfileLevel.MPEG4ProfileCoreScalable:     // 1-3
+                        case CodecProfileLevel.MPEG4ProfileAdvancedCoding:   // 1-4
+                        case CodecProfileLevel.MPEG4ProfileCore:             // 1-2
+                        case CodecProfileLevel.MPEG4ProfileAdvancedCore:     // 1-4
+                        case CodecProfileLevel.MPEG4ProfileSimpleScalable:   // 0-2
+                        case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3
+                        case CodecProfileLevel.MPEG4ProfileHybrid:           // 1-2
+                        case CodecProfileLevel.MPEG4ProfileBasicAnimated:    // 1-2
+                        case CodecProfileLevel.MPEG4ProfileScalableTexture:  // 1
+                        case CodecProfileLevel.MPEG4ProfileSimpleFace:       // 1-2
+                        case CodecProfileLevel.MPEG4ProfileSimpleFBA:        // 1-2
+                            Log.i(TAG, "Unsupported profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNSUPPORTED;
+                            supported = false;
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    if (supported) {
+                        errors &= ~ERROR_NONE_SUPPORTED;
+                    }
+                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR * 1000, maxBps);
+                    maxWidth = Math.max(W, maxWidth);
+                    maxHeight = Math.max(H, maxHeight);
+                    maxRate = Math.max(FR, maxRate);
+                }
+                applyMacroBlockLimits(maxWidth, maxHeight,
+                        maxBlocks, maxBlocksPerSecond,
+                        16 /* blockWidth */, 16 /* blockHeight */,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+                mFrameRateRange = mFrameRateRange.intersect(12, maxRate);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
+                int maxWidth = 11, maxHeight = 9, maxRate = 15;
+                maxBlocks = 99;
+                maxBlocksPerSecond = 1485;
+                maxBps = 64000;
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0;
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.H263Level10:
+                            FR = 15; W = 11; H =  9; BR =   1; MBPS =  W * H * FR; break;
+                        case CodecProfileLevel.H263Level20:
+                            // only supports CIF, 0..QCIF
+                            FR = 30; W = 22; H = 18; BR =   2; MBPS =  W * H * FR; break;
+                        case CodecProfileLevel.H263Level30:
+                            // only supports CIF, 0..QCIF
+                            FR = 30; W = 22; H = 18; BR =   6; MBPS =  W * H * FR; break;
+                        case CodecProfileLevel.H263Level40:
+                            // only supports CIF, 0..QCIF
+                            FR = 30; W = 22; H = 18; BR =  32; MBPS =  W * H * FR; break;
+                        case CodecProfileLevel.H263Level45:
+                            // only implies level 10 support
+                            FR = 30; W = 11; H =  9; BR =   2; MBPS =  W * H * FR; break;
+                        case CodecProfileLevel.H263Level50:
+                            // only supports 50fps for H > 15
+                            FR = 60; W = 22; H = 18; BR =  64; MBPS =  W * H * 50; break;
+                        case CodecProfileLevel.H263Level60:
+                            // only supports 50fps for H > 15
+                            FR = 60; W = 45; H = 18; BR = 128; MBPS =  W * H * 50; break;
+                        case CodecProfileLevel.H263Level70:
+                            // only supports 50fps for H > 30
+                            FR = 60; W = 45; H = 36; BR = 256; MBPS =  W * H * 50; break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile/level " + profileLevel.profile
+                                    + "/" + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.H263ProfileBackwardCompatible:
+                        case CodecProfileLevel.H263ProfileBaseline:
+                        case CodecProfileLevel.H263ProfileH320Coding:
+                        case CodecProfileLevel.H263ProfileHighCompression:
+                        case CodecProfileLevel.H263ProfileHighLatency:
+                        case CodecProfileLevel.H263ProfileInterlace:
+                        case CodecProfileLevel.H263ProfileInternet:
+                        case CodecProfileLevel.H263ProfileISWV2:
+                        case CodecProfileLevel.H263ProfileISWV3:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    errors &= ~ERROR_NONE_SUPPORTED;
+                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
+                    maxBlocks = Math.max(W * H, maxBlocks);
+                    maxBps = Math.max(BR * 64000, maxBps);
+                    maxWidth = Math.max(W, maxWidth);
+                    maxHeight = Math.max(H, maxHeight);
+                    maxRate = Math.max(FR, maxRate);
+                }
+                applyMacroBlockLimits(maxWidth, maxHeight,
+                        maxBlocks, maxBlocksPerSecond,
+                        16 /* blockWidth */, 16 /* blockHeight */,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+                mFrameRateRange = Range.create(1, maxRate);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) ||
+                    mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+                maxBlocks = maxBlocksPerSecond = Integer.MAX_VALUE;
+
+                // TODO: set to 100Mbps for now, need a number for VPX
+                maxBps = 100000000;
+
+                // profile levels are not indicative for VPx, but verify
+                // them nonetheless
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.VP8Level_Version0:
+                        case CodecProfileLevel.VP8Level_Version1:
+                        case CodecProfileLevel.VP8Level_Version2:
+                        case CodecProfileLevel.VP8Level_Version3:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized level "
+                                    + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.VP8ProfileMain:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    errors &= ~ERROR_NONE_SUPPORTED;
+                }
+
+                final int blockSize =
+                    mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) ? 16 : 8;
+                applyMacroBlockLimits(Short.MAX_VALUE, Short.MAX_VALUE,
+                        maxBlocks, maxBlocksPerSecond, blockSize, blockSize,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
+                maxBlocks = 36864;
+                maxBlocksPerSecond = maxBlocks * 15;
+                maxBps = 128000;
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    double FR = 0;
+                    int FS = 0;
+                    int BR = 0;
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.HEVCMainTierLevel1:
+                        case CodecProfileLevel.HEVCHighTierLevel1:
+                            FR =    15; FS =    36864; BR =    128; break;
+                        case CodecProfileLevel.HEVCMainTierLevel2:
+                        case CodecProfileLevel.HEVCHighTierLevel2:
+                            FR =    30; FS =   122880; BR =   1500; break;
+                        case CodecProfileLevel.HEVCMainTierLevel21:
+                        case CodecProfileLevel.HEVCHighTierLevel21:
+                            FR =    30; FS =   245760; BR =   3000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel3:
+                        case CodecProfileLevel.HEVCHighTierLevel3:
+                            FR =    30; FS =   552960; BR =   6000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel31:
+                        case CodecProfileLevel.HEVCHighTierLevel31:
+                            FR = 33.75; FS =   983040; BR =  10000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel4:
+                            FR =    30; FS =  2228224; BR =  12000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel4:
+                            FR =    30; FS =  2228224; BR =  30000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel41:
+                            FR =    60; FS =  2228224; BR =  20000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel41:
+                            FR =    60; FS =  2228224; BR =  50000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel5:
+                            FR =    30; FS =  8912896; BR =  25000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel5:
+                            FR =    30; FS =  8912896; BR = 100000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel51:
+                            FR =    60; FS =  8912896; BR =  40000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel51:
+                            FR =    60; FS =  8912896; BR = 160000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel52:
+                            FR =   120; FS =  8912896; BR =  60000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel52:
+                            FR =   120; FS =  8912896; BR = 240000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel6:
+                            FR =    30; FS = 35651584; BR =  60000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel6:
+                            FR =    30; FS = 35651584; BR = 240000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel61:
+                            FR =    60; FS = 35651584; BR = 120000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel61:
+                            FR =    60; FS = 35651584; BR = 480000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel62:
+                            FR =   120; FS = 35651584; BR = 240000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel62:
+                            FR =   120; FS = 35651584; BR = 800000; break;
+                        default:
+                            Log.w(TAG, "Unrecognized level "
+                                    + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.HEVCProfileMain:
+                        case CodecProfileLevel.HEVCProfileMain10:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_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;
+                    */
+
+                    errors &= ~ERROR_NONE_SUPPORTED;
+                    maxBlocksPerSecond = Math.max((int)(FR * FS), maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR * 1000, maxBps);
+                }
+
+                int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8));
+                // CTBs are at least 8x8
+                maxBlocks = Utils.divUp(maxBlocks, 8 * 8);
+                maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, 8 * 8);
+                maxLengthInBlocks = Utils.divUp(maxLengthInBlocks, 8);
+
+                applyMacroBlockLimits(
+                        maxLengthInBlocks, maxLengthInBlocks,
+                        maxBlocks, maxBlocksPerSecond,
+                        8 /* blockWidth */, 8 /* blockHeight */,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+            } else {
+                Log.w(TAG, "Unsupported mime " + mime);
+                // using minimal bitrate here.  should be overriden by
+                // info from media_codecs.xml
+                maxBps = 64000;
+                errors |= ERROR_UNSUPPORTED;
+            }
+            mBitrateRange = Range.create(1, maxBps);
+            mParent.mError |= errors;
+        }
+    }
+
+    /**
+     * A class that supports querying the encoding capabilities of a codec.
+     */
+    public static final class EncoderCapabilities {
+        /**
+         * Returns the supported range of quality values.
+         *
+         * @hide
+         */
+        public Range<Integer> getQualityRange() {
+            return mQualityRange;
+        }
+
+        /**
+         * Returns the supported range of encoder complexity values.
+         * <p>
+         * Some codecs may support multiple complexity levels, where higher
+         * complexity values use more encoder tools (e.g. perform more
+         * intensive calculations) to improve the quality or the compression
+         * ratio.  Use a lower value to save power and/or time.
+         */
+        public Range<Integer> getComplexityRange() {
+            return mComplexityRange;
+        }
+
+        /** Constant quality mode */
+        public static final int BITRATE_MODE_CQ = 0;
+        /** Variable bitrate mode */
+        public static final int BITRATE_MODE_VBR = 1;
+        /** Constant bitrate mode */
+        public static final int BITRATE_MODE_CBR = 2;
+
+        private static final Feature[] bitrates = new Feature[] {
+            new Feature("VBR", BITRATE_MODE_VBR, true),
+            new Feature("CBR", BITRATE_MODE_CBR, false),
+            new Feature("CQ",  BITRATE_MODE_CQ,  false)
+        };
+
+        private static int parseBitrateMode(String mode) {
+            for (Feature feat: bitrates) {
+                if (feat.mName.equalsIgnoreCase(mode)) {
+                    return feat.mValue;
+                }
+            }
+            return 0;
+        }
+
+        /**
+         * Query whether a bitrate mode is supported.
+         */
+        public boolean isBitrateModeSupported(int mode) {
+            for (Feature feat: bitrates) {
+                if (mode == feat.mValue) {
+                    return (mBitControl & (1 << mode)) != 0;
+                }
+            }
+            return false;
+        }
+
+        private Range<Integer> mQualityRange;
+        private Range<Integer> mComplexityRange;
+        private CodecCapabilities mParent;
+
+        /* no public constructor */
+        private EncoderCapabilities() { }
+
+        /** @hide */
+        public static EncoderCapabilities create(
+                MediaFormat info, CodecCapabilities parent) {
+            EncoderCapabilities caps = new EncoderCapabilities();
+            caps.init(info, parent);
+            return caps;
+        }
+
+        /** @hide */
+        public void init(MediaFormat info, CodecCapabilities parent) {
+            // no support for complexity or quality yet
+            mParent = parent;
+            mComplexityRange = Range.create(0, 0);
+            mQualityRange = Range.create(0, 0);
+            mBitControl = (1 << BITRATE_MODE_VBR);
+
+            applyLevelLimits();
+            parseFromInfo(info);
+        }
+
+        private void applyLevelLimits() {
+            String mime = mParent.getMimeType();
+            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
+                mComplexityRange = Range.create(0, 8);
+                mBitControl = (1 << BITRATE_MODE_CQ);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) {
+                mBitControl = (1 << BITRATE_MODE_CBR);
+            }
+        }
+
+        private int mBitControl;
+        private Integer mDefaultComplexity;
+        private Integer mDefaultQuality;
+        private String mQualityScale;
+
+        private void parseFromInfo(MediaFormat info) {
+            Map<String, Object> map = info.getMap();
+
+            if (info.containsKey("complexity-range")) {
+                mComplexityRange = Utils
+                        .parseIntRange(info.getString("complexity-range"), mComplexityRange);
+                // TODO should we limit this to level limits?
+            }
+            if (info.containsKey("quality-range")) {
+                mQualityRange = Utils
+                        .parseIntRange(info.getString("quality-range"), mQualityRange);
+            }
+            if (info.containsKey("feature-bitrate-control")) {
+                for (String mode: info.getString("feature-bitrate-control").split(",")) {
+                    mBitControl |= parseBitrateMode(mode);
+                }
+            }
+
+            try {
+                mDefaultComplexity = Integer.parseInt((String)map.get("complexity-default"));
+            } catch (NumberFormatException e) { }
+
+            try {
+                mDefaultQuality = Integer.parseInt((String)map.get("quality-default"));
+            } catch (NumberFormatException e) { }
+
+            mQualityScale = (String)map.get("quality-scale");
+        }
+
+        private boolean supports(
+                Integer complexity, Integer quality, Integer profile) {
+            boolean ok = true;
+            if (ok && complexity != null) {
+                ok = mComplexityRange.contains(complexity);
+            }
+            if (ok && quality != null) {
+                ok = mQualityRange.contains(quality);
+            }
+            if (ok && profile != null) {
+                for (CodecProfileLevel pl: mParent.profileLevels) {
+                    if (pl.profile == profile) {
+                        profile = null;
+                        break;
+                    }
+                }
+                ok = profile == null;
+            }
+            return ok;
+        }
+
+        /** @hide */
+        public void setDefaultFormat(MediaFormat format) {
+            // don't list trivial quality/complexity as default for now
+            if (!mQualityRange.getUpper().equals(mQualityRange.getLower())
+                    && mDefaultQuality != null) {
+                format.setInteger(MediaFormat.KEY_QUALITY, mDefaultQuality);
+            }
+            if (!mComplexityRange.getUpper().equals(mComplexityRange.getLower())
+                    && mDefaultComplexity != null) {
+                format.setInteger(MediaFormat.KEY_COMPLEXITY, mDefaultComplexity);
+            }
+            // bitrates are listed in order of preference
+            for (Feature feat: bitrates) {
+                if ((mBitControl & (1 << feat.mValue)) != 0) {
+                    format.setInteger(MediaFormat.KEY_BITRATE_MODE, feat.mValue);
+                    break;
+                }
+            }
+        }
+
+        /** @hide */
+        public boolean supportsFormat(MediaFormat format) {
+            final Map<String, Object> map = format.getMap();
+            final String mime = mParent.getMimeType();
+
+            Integer mode = (Integer)map.get(MediaFormat.KEY_BITRATE_MODE);
+            if (mode != null && !isBitrateModeSupported(mode)) {
+                return false;
+            }
+
+            Integer complexity = (Integer)map.get(MediaFormat.KEY_COMPLEXITY);
+            if (MediaFormat.MIMETYPE_AUDIO_FLAC.equalsIgnoreCase(mime)) {
+                Integer flacComplexity =
+                    (Integer)map.get(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL);
+                if (complexity == null) {
+                    complexity = flacComplexity;
+                } else if (flacComplexity != null && complexity != flacComplexity) {
+                    throw new IllegalArgumentException(
+                            "conflicting values for complexity and " +
+                            "flac-compression-level");
+                }
+            }
+
+            // other audio parameters
+            Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE);
+            if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mime)) {
+                Integer aacProfile = (Integer)map.get(MediaFormat.KEY_AAC_PROFILE);
+                if (profile == null) {
+                    profile = aacProfile;
+                } else if (aacProfile != null && aacProfile != profile) {
+                    throw new IllegalArgumentException(
+                            "conflicting values for profile and aac-profile");
+                }
+            }
+
+            Integer quality = (Integer)map.get(MediaFormat.KEY_QUALITY);
+
+            return supports(complexity, quality, profile);
         }
     };
 
diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java
index d74f22d..5084c5c 100644
--- a/media/java/android/media/MediaCodecList.java
+++ b/media/java/android/media/MediaCodecList.java
@@ -36,6 +36,8 @@
     /**
      * Count the number of available (regular) codecs.
      *
+     * @deprecated Use {@link #getCodecInfos} instead.
+     *
      * @see #REGULAR_CODECS
      */
     public static final int getCodecCount() {
@@ -49,6 +51,8 @@
      * Return the {@link MediaCodecInfo} object for the codec at
      * the given {@code index} in the regular list.
      *
+     * @deprecated Use {@link #getCodecInfos} instead.
+     *
      * @see #REGULAR_CODECS
      */
     public static final MediaCodecInfo getCodecInfoAt(int index) {
@@ -116,13 +120,22 @@
 
     /**
      * Use in {@link #MediaCodecList} to enumerate only codecs that are suitable
-     * for normal playback and recording.
+     * for regular (buffer-to-buffer) decoding or encoding.
+     *
+     * <em>NOTE:</em> These are the codecs that are returned prior to API 21,
+     * using the now deprecated static methods.
      */
     public static final int REGULAR_CODECS = 0;
 
     /**
      * Use in {@link #MediaCodecList} to enumerate all codecs, even ones that are
-     * not suitable for normal playback or recording.
+     * not suitable for regular (buffer-to-buffer) decoding or encoding.  These
+     * include codecs, for example, that only work with special input or output
+     * surfaces, such as secure-only or tunneled-only codecs.
+     *
+     * @see MediaCodecInfo.CodecCapabilities#isFormatSupported
+     * @see MediaCodecInfo.CodecCapabilities#FEATURE_SecurePlayback
+     * @see MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback
      */
     public static final int ALL_CODECS = 1;
 
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index fd79495..2036533 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -120,19 +120,6 @@
     private Map<String, Object> mMap;
 
     /**
-     * A key prefix used together with a {@link MediaCodecInfo.CodecCapabilities}
-     * feature name describing a required or optional feature for a codec capabilities
-     * query.
-     * The associated value is an integer, where non-0 value means the feature is
-     * requested to be present, while 0 value means the feature is requested to be not
-     * present.
-     * @see MediaCodecList#findDecoderForFormat
-     * @see MediaCodecList#findEncoderForFormat
-     * @see MediaCodecInfo.CodecCapabilities#isFormatSupported
-     */
-    public static final String KEY_FEATURE_ = "feature-";
-
-    /**
      * A key describing the mime type of the MediaFormat.
      * The associated value is a string.
      */
@@ -422,6 +409,8 @@
      * codec specific, but lower values generally result in more efficient
      * (smaller-sized) encoding.
      *
+     * @hide
+     *
      * @see MediaCodecInfo.CodecCapabilities.EncoderCapabilities#getQualityRange
      */
     public static final String KEY_QUALITY = "quality";
@@ -510,6 +499,21 @@
     }
 
     /**
+     * A key prefix used together with a {@link MediaCodecInfo.CodecCapabilities}
+     * feature name describing a required or optional feature for a codec capabilities
+     * query.
+     * The associated value is an integer, where non-0 value means the feature is
+     * requested to be present, while 0 value means the feature is requested to be not
+     * present.
+     * @see MediaCodecList#findDecoderForFormat
+     * @see MediaCodecList#findEncoderForFormat
+     * @see MediaCodecInfo.CodecCapabilities#isFormatSupported
+     *
+     * @hide
+     */
+    public static final String KEY_FEATURE_ = "feature-";
+
+    /**
      * Returns the value of an integer key.
      */
     public final int getInteger(String name) {
@@ -559,6 +563,23 @@
     }
 
     /**
+     * Returns whether a feature is to be enabled ({@code true}) or disabled
+     * ({@code false}).
+     *
+     * @param feature the name of a {@link MediaCodecInfo.CodecCapabilities} feature.
+     *
+     * @throws IllegalArgumentException if the feature was neither set to be enabled
+     *        nor to be disabled.
+     */
+    public boolean getFeatureEnabled(String feature) {
+        Integer enabled = (Integer)mMap.get(KEY_FEATURE_ + feature);
+        if (enabled == null) {
+            throw new IllegalArgumentException("feature is not specified");
+        }
+        return enabled != 0;
+    }
+
+    /**
      * Sets the value of an integer key.
      */
     public final void setInteger(String name, int value) {
@@ -594,6 +615,23 @@
     }
 
     /**
+     * Sets whether a feature is to be enabled ({@code true}) or disabled
+     * ({@code false}).
+     *
+     * If {@code enabled} is {@code true}, the feature is requested to be present.
+     * Otherwise, the feature is requested to be not present.
+     *
+     * @param feature the name of a {@link MediaCodecInfo.CodecCapabilities} feature.
+     *
+     * @see MediaCodecList#findDecoderForFormat
+     * @see MediaCodecList#findEncoderForFormat
+     * @see MediaCodecInfo.CodecCapabilities#isFormatSupported
+     */
+    public void setFeatureEnabled(String feature, boolean enabled) {
+        setInteger(KEY_FEATURE_ + feature, enabled ? 1 : 0);
+    }
+
+    /**
      * Creates a minimal audio format.
      * @param mime The mime type of the content.
      * @param sampleRate The sampling rate of the content.
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 3949d7d..14bf10e 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -88,14 +88,4 @@
         android:orientation="vertical"
         android:paddingBottom="@dimen/qs_panel_padding" />
 
-    <TextView
-        android:id="@+id/zen_alarm_warning"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/qs_panel_padding"
-        android:paddingLeft="@dimen/qs_panel_padding"
-        android:paddingRight="@dimen/qs_panel_padding"
-        android:paddingTop="4dp"
-        android:paddingBottom="4dp"
-        android:textAppearance="@style/TextAppearance.QS.Subhead" />
 </com.android.systemui.volume.ZenModePanel>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 726a54f..0e18979 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -200,5 +200,8 @@
 
     <!-- Tiles with feature timeouts: number of days to show after feature is used. -->
     <integer name="days_to_show_timeout_tiles">30</integer>
+
+    <!-- Number of times to show the strong alarm warning text in the volume dialog -->
+    <integer name="zen_mode_alarm_warning_threshold">5</integer>
 </resources>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 189c052..b000a48 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -697,7 +697,7 @@
     <string name="description_direction_left">"Slide left for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
 
     <!-- Zen mode: No interruptions title, with a warning about alarms. [CHAR LIMIT=60] -->
-    <string name="zen_no_interruptions_with_warning">No interruptions, including alarms</string>
+    <string name="zen_no_interruptions_with_warning">No interruptions. Not even alarms.</string>
 
     <!-- Zen mode: No interruptions. [CHAR LIMIT=40] -->
     <string name="zen_no_interruptions">No interruptions</string>
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index c99e1fd..ac7fc25 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -31,10 +31,9 @@
 import android.provider.Settings.Global;
 import android.service.notification.Condition;
 import android.service.notification.ZenModeConfig;
-import android.text.format.DateFormat;
-import android.text.format.Time;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.MathUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.animation.AnimationUtils;
@@ -49,10 +48,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.ZenModeController;
 
-import java.text.SimpleDateFormat;
 import java.util.Arrays;
-import java.util.Date;
-import java.util.Locale;
 import java.util.Objects;
 
 public class ZenModePanel extends LinearLayout {
@@ -79,10 +75,10 @@
     private final Context mContext;
     private final LayoutInflater mInflater;
     private final H mHandler = new H();
-    private final Favorites mFavorites;
+    private final Prefs mPrefs;
     private final Interpolator mFastOutSlowInInterpolator;
-    private final int mHardWarningColor;
-    private final int mSoftWarningColor;
+    private final int mSubheadWarningColor;
+    private final int mSubheadColor;
 
     private String mTag = TAG + "/" + Integer.toHexString(System.identityHashCode(this));
 
@@ -92,7 +88,6 @@
     private TextView mZenSubheadExpanded;
     private View mMoreSettings;
     private LinearLayout mZenConditions;
-    private TextView mAlarmWarning;
 
     private Callback mCallback;
     private ZenModeController mController;
@@ -103,21 +98,21 @@
     private boolean mExpanded;
     private boolean mHidden = false;
     private int mSessionZen;
+    private int mAttachedZen;
     private Condition mSessionExitCondition;
-    private long mNextAlarm;
     private Condition[] mConditions;
     private Condition mTimeCondition;
 
     public ZenModePanel(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
-        mFavorites = new Favorites();
+        mPrefs = new Prefs();
         mInflater = LayoutInflater.from(mContext.getApplicationContext());
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(mContext,
                 android.R.interpolator.fast_out_slow_in);
         final Resources res = mContext.getResources();
-        mHardWarningColor = res.getColor(R.color.system_warning_color);
-        mSoftWarningColor = res.getColor(R.color.qs_subhead);
+        mSubheadWarningColor = res.getColor(R.color.system_warning_color);
+        mSubheadColor = res.getColor(R.color.qs_subhead);
         if (DEBUG) Log.d(mTag, "new ZenModePanel");
     }
 
@@ -155,17 +150,16 @@
         });
 
         mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions);
-        mAlarmWarning = (TextView) findViewById(R.id.zen_alarm_warning);
     }
 
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         if (DEBUG) Log.d(mTag, "onAttachedToWindow");
-        mSessionZen = getSelectedZen(-1);
+        mAttachedZen = getSelectedZen(-1);
+        mSessionZen = mAttachedZen;
         mSessionExitCondition = copy(mExitCondition);
         refreshExitConditionText();
-        refreshNextAlarm();
         updateWidgets();
     }
 
@@ -173,6 +167,8 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         if (DEBUG) Log.d(mTag, "onDetachedFromWindow");
+        checkForAttachedZenChange();
+        mAttachedZen = -1;
         mSessionZen = -1;
         mSessionExitCondition = null;
         setExpanded(false);
@@ -184,6 +180,17 @@
         updateWidgets();
     }
 
+    private void checkForAttachedZenChange() {
+        final int selectedZen = getSelectedZen(-1);
+        if (DEBUG) Log.d(mTag, "selectedZen=" + selectedZen);
+        if (selectedZen != mAttachedZen) {
+            if (DEBUG) Log.d(mTag, "attachedZen: " + mAttachedZen + " -> " + selectedZen);
+            if (selectedZen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
+                mPrefs.trackNoneSelected();
+            }
+        }
+    }
+
     private void setExpanded(boolean expanded) {
         if (expanded == mExpanded) return;
         mExpanded = expanded;
@@ -234,10 +241,6 @@
         updateWidgets();
     }
 
-    private Uri getExitConditionId() {
-        return getConditionId(mExitCondition);
-    }
-
     private static Uri getConditionId(Condition condition) {
         return condition != null ? condition.id : null;
     }
@@ -301,9 +304,7 @@
         final boolean zenOff = zen == Global.ZEN_MODE_OFF;
         final boolean zenImportant = zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
-        final boolean hasNextAlarm = mNextAlarm != 0;
         final boolean expanded = !mHidden && mExpanded;
-        final boolean showAlarmWarning = zenNone && expanded && hasNextAlarm;
 
         mZenButtons.setVisibility(mHidden ? GONE : VISIBLE);
         mZenSubhead.setVisibility(!mHidden && !zenOff ? VISIBLE : GONE);
@@ -311,26 +312,6 @@
         mZenSubheadCollapsed.setVisibility(!expanded ? VISIBLE : GONE);
         mMoreSettings.setVisibility(zenImportant && expanded ? VISIBLE : GONE);
         mZenConditions.setVisibility(!zenOff && expanded ? VISIBLE : GONE);
-        mAlarmWarning.setVisibility(zenNone && expanded && hasNextAlarm ? VISIBLE : GONE);
-        if (showAlarmWarning) {
-            final long exitTime = ZenModeConfig.tryParseCountdownConditionId(getExitConditionId());
-            final long now = System.currentTimeMillis();
-            final boolean alarmToday = time(mNextAlarm).yearDay == time(now).yearDay;
-            final String skeleton = (alarmToday ? "" : "E")
-                    + (DateFormat.is24HourFormat(mContext) ? "Hm" : "hma");
-            final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
-            final String alarm = new SimpleDateFormat(pattern).format(new Date(mNextAlarm));
-            final boolean isWarning = exitTime > 0 && mNextAlarm > now && mNextAlarm < exitTime;
-            if (isWarning) {
-                mAlarmWarning.setText(mContext.getString(R.string.zen_alarm_warning, alarm));
-                mAlarmWarning.setTextColor(mHardWarningColor);
-            } else {
-                mAlarmWarning.setText(mContext.getString(alarmToday
-                        ? R.string.zen_alarm_information_time
-                        : R.string.zen_alarm_information_day_time, alarm));
-                mAlarmWarning.setTextColor(mSoftWarningColor);
-            }
-        }
 
         if (zenNone) {
             mZenSubheadExpanded.setText(R.string.zen_no_interruptions_with_warning);
@@ -339,12 +320,8 @@
             mZenSubheadExpanded.setText(R.string.zen_important_interruptions);
             mZenSubheadCollapsed.setText(mExitConditionText);
         }
-    }
-
-    private static Time time(long millis) {
-        final Time t = new Time();
-        t.set(millis);
-        return t;
+        mZenSubheadExpanded.setTextColor(zenNone && mPrefs.isNoneDangerous()
+                ? mSubheadWarningColor : mSubheadColor);
     }
 
     private Condition parseExistingTimeCondition(Condition condition) {
@@ -373,15 +350,6 @@
                 Condition.FLAG_RELEVANT_NOW);
     }
 
-    private void refreshNextAlarm() {
-        mNextAlarm = mController.getNextAlarm();
-    }
-
-    private void handleNextAlarmChanged() {
-        refreshNextAlarm();
-        updateWidgets();
-    }
-
     private void handleUpdateConditions(Condition[] conditions) {
         mConditions = conditions;
         handleUpdateConditions();
@@ -429,7 +397,7 @@
             }
         }
         if (DEBUG) Log.d(mTag, "Selecting a default");
-        final int favoriteIndex = mFavorites.getMinuteIndex();
+        final int favoriteIndex = mPrefs.getMinuteIndex();
         if (favoriteIndex == -1) {
             getConditionTagAt(FOREVER_CONDITION_INDEX).rb.setChecked(true);
         } else {
@@ -579,9 +547,9 @@
         }
         setExitCondition(condition);
         if (condition == null) {
-            mFavorites.setMinuteIndex(-1);
+            mPrefs.setMinuteIndex(-1);
         } else if (ZenModeConfig.isValidCountdownConditionId(condition.id) && mBucketIndex != -1) {
-            mFavorites.setMinuteIndex(mBucketIndex);
+            mPrefs.setMinuteIndex(mBucketIndex);
         }
         mSessionExitCondition = copy(condition);
     }
@@ -618,18 +586,12 @@
         public void onExitConditionChanged(Condition exitCondition) {
             mHandler.obtainMessage(H.EXIT_CONDITION_CHANGED, exitCondition).sendToTarget();
         }
-
-        @Override
-        public void onNextAlarmChanged() {
-            mHandler.sendEmptyMessage(H.NEXT_ALARM_CHANGED);
-        }
     };
 
     private final class H extends Handler {
         private static final int UPDATE_CONDITIONS = 1;
         private static final int EXIT_CONDITION_CHANGED = 2;
         private static final int UPDATE_ZEN = 3;
-        private static final int NEXT_ALARM_CHANGED = 4;
 
         private H() {
             super(Looper.getMainLooper());
@@ -643,8 +605,6 @@
                 handleExitConditionChanged((Condition) msg.obj);
             } else if (msg.what == UPDATE_ZEN) {
                 handleUpdateZen(msg.arg1);
-            } else if (msg.what == NEXT_ALARM_CHANGED) {
-                handleNextAlarmChanged();
             }
         }
     }
@@ -661,14 +621,32 @@
         Condition condition;
     }
 
-    private final class Favorites implements OnSharedPreferenceChangeListener {
+    private final class Prefs implements OnSharedPreferenceChangeListener {
         private static final String KEY_MINUTE_INDEX = "minuteIndex";
+        private static final String KEY_NONE_SELECTED = "noneSelected";
+
+        private final int mNoneDangerousThreshold;
 
         private int mMinuteIndex;
+        private int mNoneSelected;
 
-        private Favorites() {
+        private Prefs() {
+            mNoneDangerousThreshold = mContext.getResources()
+                    .getInteger(R.integer.zen_mode_alarm_warning_threshold);
             prefs().registerOnSharedPreferenceChangeListener(this);
             updateMinuteIndex();
+            updateNoneSelected();
+        }
+
+        public boolean isNoneDangerous() {
+            return mNoneSelected < mNoneDangerousThreshold;
+        }
+
+        public void trackNoneSelected() {
+            mNoneSelected = clampNoneSelected(mNoneSelected + 1);
+            if (DEBUG) Log.d(mTag, "Setting none selected: " + mNoneSelected + " threshold="
+                    + mNoneDangerousThreshold);
+            prefs().edit().putInt(KEY_NONE_SELECTED, mNoneSelected).apply();
         }
 
         public int getMinuteIndex() {
@@ -676,9 +654,9 @@
         }
 
         public void setMinuteIndex(int minuteIndex) {
-            minuteIndex = clamp(minuteIndex);
+            minuteIndex = clampIndex(minuteIndex);
             if (minuteIndex == mMinuteIndex) return;
-            mMinuteIndex = clamp(minuteIndex);
+            mMinuteIndex = clampIndex(minuteIndex);
             if (DEBUG) Log.d(mTag, "Setting favorite minute index: " + mMinuteIndex);
             prefs().edit().putInt(KEY_MINUTE_INDEX, mMinuteIndex).apply();
         }
@@ -686,6 +664,7 @@
         @Override
         public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
             updateMinuteIndex();
+            updateNoneSelected();
         }
 
         private SharedPreferences prefs() {
@@ -693,12 +672,21 @@
         }
 
         private void updateMinuteIndex() {
-            mMinuteIndex = clamp(prefs().getInt(KEY_MINUTE_INDEX, DEFAULT_BUCKET_INDEX));
+            mMinuteIndex = clampIndex(prefs().getInt(KEY_MINUTE_INDEX, DEFAULT_BUCKET_INDEX));
             if (DEBUG) Log.d(mTag, "Favorite minute index: " + mMinuteIndex);
         }
 
-        private int clamp(int index) {
-            return Math.max(-1, Math.min(MINUTE_BUCKETS.length - 1, index));
+        private int clampIndex(int index) {
+            return MathUtils.constrain(index, -1, MINUTE_BUCKETS.length - 1);
+        }
+
+        private void updateNoneSelected() {
+            mNoneSelected = clampNoneSelected(prefs().getInt(KEY_NONE_SELECTED, 0));
+            if (DEBUG) Log.d(mTag, "None selected: " + mNoneSelected);
+        }
+
+        private int clampNoneSelected(int noneSelected) {
+            return MathUtils.constrain(noneSelected, 0, Integer.MAX_VALUE);
         }
     }
 
