Merge "MediaCodec:Add code for YCbCrP010 format support" am: f33f4b6f50
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1894875 Change-Id: I3fa5f2731b0d91aef0f197761bd96d1a4c94e7ee
This commit is contained in:
@@ -163,6 +163,14 @@ public abstract class Image implements AutoCloseable {
|
|||||||
* {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}.
|
* {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}.
|
||||||
* </td>
|
* </td>
|
||||||
* </tr>
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td>{@link android.graphics.ImageFormat#YCBCR_P010 YCBCR_P010}</td>
|
||||||
|
* <td>1</td>
|
||||||
|
* <td>P010 is a 4:2:0 YCbCr semiplanar format comprised of a WxH Y plane
|
||||||
|
* followed by a Wx(H/2) CbCr plane. Each sample is represented by a 16-bit
|
||||||
|
* little-endian value, with the lower 6 bits set to zero.
|
||||||
|
* </td>
|
||||||
|
* </tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
* @see android.graphics.ImageFormat
|
* @see android.graphics.ImageFormat
|
||||||
|
|||||||
@@ -5107,7 +5107,6 @@ final public class MediaCodec {
|
|||||||
public MediaImage(
|
public MediaImage(
|
||||||
@NonNull ByteBuffer buffer, @NonNull ByteBuffer info, boolean readOnly,
|
@NonNull ByteBuffer buffer, @NonNull ByteBuffer info, boolean readOnly,
|
||||||
long timestamp, int xOffset, int yOffset, @Nullable Rect cropRect) {
|
long timestamp, int xOffset, int yOffset, @Nullable Rect cropRect) {
|
||||||
mFormat = ImageFormat.YUV_420_888;
|
|
||||||
mTimestamp = timestamp;
|
mTimestamp = timestamp;
|
||||||
mIsImageValid = true;
|
mIsImageValid = true;
|
||||||
mIsReadOnly = buffer.isReadOnly();
|
mIsReadOnly = buffer.isReadOnly();
|
||||||
@@ -5120,6 +5119,11 @@ final public class MediaCodec {
|
|||||||
|
|
||||||
mBufferContext = 0;
|
mBufferContext = 0;
|
||||||
|
|
||||||
|
int cbPlaneOffset = -1;
|
||||||
|
int crPlaneOffset = -1;
|
||||||
|
int planeOffsetInc = -1;
|
||||||
|
int pixelStride = -1;
|
||||||
|
|
||||||
// read media-info. See MediaImage2
|
// read media-info. See MediaImage2
|
||||||
if (info.remaining() == 104) {
|
if (info.remaining() == 104) {
|
||||||
int type = info.getInt();
|
int type = info.getInt();
|
||||||
@@ -5137,14 +5141,27 @@ final public class MediaCodec {
|
|||||||
"unsupported size: " + mWidth + "x" + mHeight);
|
"unsupported size: " + mWidth + "x" + mHeight);
|
||||||
}
|
}
|
||||||
int bitDepth = info.getInt();
|
int bitDepth = info.getInt();
|
||||||
if (bitDepth != 8) {
|
if (bitDepth != 8 && bitDepth != 10) {
|
||||||
throw new UnsupportedOperationException("unsupported bit depth: " + bitDepth);
|
throw new UnsupportedOperationException("unsupported bit depth: " + bitDepth);
|
||||||
}
|
}
|
||||||
int bitDepthAllocated = info.getInt();
|
int bitDepthAllocated = info.getInt();
|
||||||
if (bitDepthAllocated != 8) {
|
if (bitDepthAllocated != 8 && bitDepthAllocated != 16) {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"unsupported allocated bit depth: " + bitDepthAllocated);
|
"unsupported allocated bit depth: " + bitDepthAllocated);
|
||||||
}
|
}
|
||||||
|
if (bitDepth == 8 && bitDepthAllocated == 8) {
|
||||||
|
mFormat = ImageFormat.YUV_420_888;
|
||||||
|
planeOffsetInc = 1;
|
||||||
|
pixelStride = 2;
|
||||||
|
} else if (bitDepth == 10 && bitDepthAllocated == 16) {
|
||||||
|
mFormat = ImageFormat.YCBCR_P010;
|
||||||
|
planeOffsetInc = 2;
|
||||||
|
pixelStride = 4;
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("couldn't infer ImageFormat"
|
||||||
|
+ " bitDepth: " + bitDepth + " bitDepthAllocated: " + bitDepthAllocated);
|
||||||
|
}
|
||||||
|
|
||||||
mPlanes = new MediaPlane[numPlanes];
|
mPlanes = new MediaPlane[numPlanes];
|
||||||
for (int ix = 0; ix < numPlanes; ix++) {
|
for (int ix = 0; ix < numPlanes; ix++) {
|
||||||
int planeOffset = info.getInt();
|
int planeOffset = info.getInt();
|
||||||
@@ -5166,12 +5183,31 @@ final public class MediaCodec {
|
|||||||
buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8)
|
buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8)
|
||||||
+ (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * colInc);
|
+ (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * colInc);
|
||||||
mPlanes[ix] = new MediaPlane(buffer.slice(), rowInc, colInc);
|
mPlanes[ix] = new MediaPlane(buffer.slice(), rowInc, colInc);
|
||||||
|
if ((mFormat == ImageFormat.YUV_420_888 || mFormat == ImageFormat.YCBCR_P010)
|
||||||
|
&& ix == 1) {
|
||||||
|
cbPlaneOffset = planeOffset;
|
||||||
|
} else if ((mFormat == ImageFormat.YUV_420_888
|
||||||
|
|| mFormat == ImageFormat.YCBCR_P010) && ix == 2) {
|
||||||
|
crPlaneOffset = planeOffset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"unsupported info length: " + info.remaining());
|
"unsupported info length: " + info.remaining());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate chroma semiplanerness.
|
||||||
|
if (mFormat == ImageFormat.YCBCR_P010) {
|
||||||
|
if (crPlaneOffset != cbPlaneOffset + planeOffsetInc) {
|
||||||
|
throw new UnsupportedOperationException("Invalid plane offsets"
|
||||||
|
+ " cbPlaneOffset: " + cbPlaneOffset + " crPlaneOffset: " + crPlaneOffset);
|
||||||
|
}
|
||||||
|
if (mPlanes[1].getPixelStride() != pixelStride
|
||||||
|
|| mPlanes[2].getPixelStride() != pixelStride) {
|
||||||
|
throw new UnsupportedOperationException("Invalid pixelStride");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cropRect == null) {
|
if (cropRect == null) {
|
||||||
cropRect = new Rect(0, 0, mWidth, mHeight);
|
cropRect = new Rect(0, 0, mWidth, mHeight);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user