Loading media/java/android/media/Image.java +8 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,14 @@ public abstract class Image implements AutoCloseable { * {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}. * </td> * </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> * * @see android.graphics.ImageFormat Loading media/java/android/media/MediaCodec.java +39 −3 Original line number Diff line number Diff line Loading @@ -5107,7 +5107,6 @@ final public class MediaCodec { public MediaImage( @NonNull ByteBuffer buffer, @NonNull ByteBuffer info, boolean readOnly, long timestamp, int xOffset, int yOffset, @Nullable Rect cropRect) { mFormat = ImageFormat.YUV_420_888; mTimestamp = timestamp; mIsImageValid = true; mIsReadOnly = buffer.isReadOnly(); Loading @@ -5120,6 +5119,11 @@ final public class MediaCodec { mBufferContext = 0; int cbPlaneOffset = -1; int crPlaneOffset = -1; int planeOffsetInc = -1; int pixelStride = -1; // read media-info. See MediaImage2 if (info.remaining() == 104) { int type = info.getInt(); Loading @@ -5137,14 +5141,27 @@ final public class MediaCodec { "unsupported size: " + mWidth + "x" + mHeight); } int bitDepth = info.getInt(); if (bitDepth != 8) { if (bitDepth != 8 && bitDepth != 10) { throw new UnsupportedOperationException("unsupported bit depth: " + bitDepth); } int bitDepthAllocated = info.getInt(); if (bitDepthAllocated != 8) { if (bitDepthAllocated != 8 && bitDepthAllocated != 16) { throw new UnsupportedOperationException( "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]; for (int ix = 0; ix < numPlanes; ix++) { int planeOffset = info.getInt(); Loading @@ -5166,12 +5183,31 @@ final public class MediaCodec { buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8) + (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * 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 { throw new UnsupportedOperationException( "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) { cropRect = new Rect(0, 0, mWidth, mHeight); } Loading Loading
media/java/android/media/Image.java +8 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,14 @@ public abstract class Image implements AutoCloseable { * {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}. * </td> * </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> * * @see android.graphics.ImageFormat Loading
media/java/android/media/MediaCodec.java +39 −3 Original line number Diff line number Diff line Loading @@ -5107,7 +5107,6 @@ final public class MediaCodec { public MediaImage( @NonNull ByteBuffer buffer, @NonNull ByteBuffer info, boolean readOnly, long timestamp, int xOffset, int yOffset, @Nullable Rect cropRect) { mFormat = ImageFormat.YUV_420_888; mTimestamp = timestamp; mIsImageValid = true; mIsReadOnly = buffer.isReadOnly(); Loading @@ -5120,6 +5119,11 @@ final public class MediaCodec { mBufferContext = 0; int cbPlaneOffset = -1; int crPlaneOffset = -1; int planeOffsetInc = -1; int pixelStride = -1; // read media-info. See MediaImage2 if (info.remaining() == 104) { int type = info.getInt(); Loading @@ -5137,14 +5141,27 @@ final public class MediaCodec { "unsupported size: " + mWidth + "x" + mHeight); } int bitDepth = info.getInt(); if (bitDepth != 8) { if (bitDepth != 8 && bitDepth != 10) { throw new UnsupportedOperationException("unsupported bit depth: " + bitDepth); } int bitDepthAllocated = info.getInt(); if (bitDepthAllocated != 8) { if (bitDepthAllocated != 8 && bitDepthAllocated != 16) { throw new UnsupportedOperationException( "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]; for (int ix = 0; ix < numPlanes; ix++) { int planeOffset = info.getInt(); Loading @@ -5166,12 +5183,31 @@ final public class MediaCodec { buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8) + (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * 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 { throw new UnsupportedOperationException( "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) { cropRect = new Rect(0, 0, mWidth, mHeight); } Loading