Merge "media: add macroblockrate to PerformancePoint"
This commit is contained in:
@@ -24538,7 +24538,9 @@ package android.media {
|
||||
}
|
||||
|
||||
public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint {
|
||||
ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int);
|
||||
method public boolean covers(@NonNull android.media.MediaFormat);
|
||||
method public boolean covers(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint);
|
||||
field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_100;
|
||||
field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_120;
|
||||
field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_200;
|
||||
@@ -24573,8 +24575,8 @@ package android.media {
|
||||
field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_50;
|
||||
field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_60;
|
||||
field public final int frameRate;
|
||||
field public final int height;
|
||||
field public final int width;
|
||||
field public final long macroBlockRate;
|
||||
field public final int macroBlocks;
|
||||
}
|
||||
|
||||
public final class MediaCodecList {
|
||||
|
||||
@@ -1614,29 +1614,59 @@ public final class MediaCodecInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Video performance points are a set of standard performance points defined by pixel rate.
|
||||
* Video performance points are a set of standard performance points defined by number of
|
||||
* pixels, pixel rate and frame rate. Performance point represents an upper bound. This
|
||||
* means that it covers all performance points with fewer pixels, pixel rate and frame
|
||||
* rate.
|
||||
*/
|
||||
public static final class PerformancePoint {
|
||||
/**
|
||||
* Frame width in pixels.
|
||||
* (Maximum) number of macroblocks in the frame.
|
||||
*
|
||||
* Video frames are conceptually divided into 16-by-16 pixel blocks called macroblocks.
|
||||
* Most coding standards operate on these 16-by-16 pixel blocks; thus, codec performance
|
||||
* is characterized using such blocks.
|
||||
*/
|
||||
public final int width;
|
||||
public final int macroBlocks;
|
||||
|
||||
/**
|
||||
* Frame height in pixels.
|
||||
*/
|
||||
public final int height;
|
||||
|
||||
/**
|
||||
* Frame rate in frames per second.
|
||||
* (Maximum) frame rate in frames per second.
|
||||
*/
|
||||
public final int frameRate;
|
||||
|
||||
/**
|
||||
* (Maximum) number of macroblocks processed per second.
|
||||
*/
|
||||
public final long macroBlockRate;
|
||||
|
||||
/* package private */
|
||||
PerformancePoint(int width_, int height_, int frameRate_) {
|
||||
width = width_;
|
||||
height = height_;
|
||||
frameRate = frameRate_;
|
||||
PerformancePoint(int width_, int height_, int frameRate_, int maxFrameRate_) {
|
||||
macroBlocks = saturateLongToInt(
|
||||
((Math.max(1, (long)width_) + 15) / 16)
|
||||
* ((Math.max(1, (long)height_) + 15) / 16));
|
||||
frameRate = Math.max(1, frameRate_);
|
||||
macroBlockRate = Math.max(maxFrameRate_, frameRate) * macroBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a performance point for a given frame size and frame rate.
|
||||
*
|
||||
* @param width_ width of the frame in pixels
|
||||
* @param height_ height of the frame in pixels
|
||||
* @param frameRate_ frame rate in frames per second
|
||||
*/
|
||||
public PerformancePoint(int width_, int height_, int frameRate_) {
|
||||
this(width_, height_, frameRate_, frameRate_ /* maxFrameRate */);
|
||||
}
|
||||
|
||||
private int saturateLongToInt(long value) {
|
||||
if (value < Integer.MIN_VALUE) {
|
||||
return Integer.MIN_VALUE;
|
||||
} else if (value > Integer.MAX_VALUE) {
|
||||
return Integer.MAX_VALUE;
|
||||
} else {
|
||||
return (int)value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1647,26 +1677,40 @@ public final class MediaCodecInfo {
|
||||
* @return {@code true} if the performance point covers the format.
|
||||
*/
|
||||
public boolean covers(@NonNull MediaFormat format) {
|
||||
// for simplicity, this code assumes a 16x16 block size.
|
||||
long macroBlocks = ((width + 15) / 16) * (long)((height + 15) / 16);
|
||||
long mbps = macroBlocks * frameRate;
|
||||
|
||||
long formatMacroBlocks =
|
||||
(long)((format.getInteger(MediaFormat.KEY_WIDTH, 0) + 15) / 16)
|
||||
* ((format.getInteger(MediaFormat.KEY_HEIGHT, 0) + 15) / 16);
|
||||
double formatMbps =
|
||||
Math.ceil(formatMacroBlocks
|
||||
* format.getNumber(MediaFormat.KEY_FRAME_RATE, 0).doubleValue());
|
||||
return formatMacroBlocks > 0 && formatMacroBlocks <= macroBlocks
|
||||
&& formatMbps <= mbps;
|
||||
PerformancePoint other = new PerformancePoint(
|
||||
format.getInteger(MediaFormat.KEY_WIDTH, 0),
|
||||
format.getInteger(MediaFormat.KEY_HEIGHT, 0),
|
||||
// safely convert ceil(double) to int through float case and Math.round
|
||||
Math.round((float)(
|
||||
Math.ceil(format.getNumber(MediaFormat.KEY_FRAME_RATE, 0)
|
||||
.doubleValue()))));
|
||||
return covers(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the performance point covers another performance point. Use this
|
||||
* method to determine if a performance point advertised by a codec covers the
|
||||
* performance point required. This method can also be used for lose ordering as this
|
||||
* method is transitive.
|
||||
*
|
||||
* @param other other performance point considered
|
||||
*
|
||||
* @return {@code true} if the performance point covers the other.
|
||||
*/
|
||||
public boolean covers(@NonNull PerformancePoint other) {
|
||||
return (macroBlocks >= other.macroBlocks
|
||||
&& frameRate >= other.frameRate
|
||||
&& macroBlockRate >= other.macroBlockRate);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof PerformancePoint) {
|
||||
PerformancePoint other = (PerformancePoint)o;
|
||||
return ((long)width * height) == ((long)other.width * other.height)
|
||||
&& frameRate == other.frameRate;
|
||||
return (macroBlocks == other.macroBlocks
|
||||
&& frameRate == other.frameRate
|
||||
&& macroBlockRate == other.macroBlockRate);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1931,7 +1975,8 @@ public final class MediaCodecInfo {
|
||||
continue;
|
||||
}
|
||||
ret.add(new PerformancePoint(
|
||||
size.getWidth(), size.getHeight(), range.getLower().intValue()));
|
||||
size.getWidth(), size.getHeight(), range.getLower().intValue(),
|
||||
range.getUpper().intValue()));
|
||||
}
|
||||
// check if the component specified no performance point indication
|
||||
if (ret.size() == 0) {
|
||||
@@ -1939,9 +1984,12 @@ public final class MediaCodecInfo {
|
||||
}
|
||||
|
||||
// sort reversed by area first, then by frame rate
|
||||
ret.sort((a, b) -> (a.width * a.height != b.width * b.height ?
|
||||
(b.width * b.height - a.width * a.height) :
|
||||
(b.frameRate - a.frameRate)));
|
||||
ret.sort((a, b) -> -((a.macroBlocks != b.macroBlocks) ?
|
||||
(a.macroBlocks < b.macroBlocks ? -1 : 1) :
|
||||
(a.macroBlockRate != b.macroBlockRate) ?
|
||||
(a.macroBlockRate < b.macroBlockRate ? -1 : 1) :
|
||||
(a.frameRate != b.frameRate) ?
|
||||
(a.frameRate < b.frameRate ? -1 : 1) : 0));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user