Commit ee50dff9 authored by Sandeep Vijayasekar's avatar Sandeep Vijayasekar Committed by Commit Bot

Set color space and HDR metadata in android.media.MediaFormat

Used by MediaCodec to display HDR content
Bug:internal b/68950223
Test:none

Change-Id: I6db3a1e5ce8e74ee6614d557edc7351b75306f2d
Reviewed-on: https://chromium-review.googlesource.com/756443
Commit-Queue: Sandeep Vijayasekar <sandv@chromium.org>
Reviewed-by: default avatarSergey Volk <servolk@chromium.org>
Reviewed-by: default avatarFredrik Hubinette <hubbe@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521165}
parent bdccc14a
...@@ -22,6 +22,7 @@ import org.chromium.media.MediaCodecUtil.BitrateAdjustmentTypes; ...@@ -22,6 +22,7 @@ import org.chromium.media.MediaCodecUtil.BitrateAdjustmentTypes;
import org.chromium.media.MediaCodecUtil.MimeTypes; import org.chromium.media.MediaCodecUtil.MimeTypes;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/** /**
* A MediaCodec wrapper for adapting the API and catching exceptions. * A MediaCodec wrapper for adapting the API and catching exceptions.
...@@ -52,6 +53,8 @@ class MediaCodecBridge { ...@@ -52,6 +53,8 @@ class MediaCodecBridge {
private static final int BITRATE_ADJUSTMENT_FPS = 30; private static final int BITRATE_ADJUSTMENT_FPS = 30;
private static final int MAXIMUM_INITIAL_FPS = 30; private static final int MAXIMUM_INITIAL_FPS = 30;
private static final int MAX_CHROMATICITY = 50000; // Defined in CTA-861.3.
protected MediaCodec mMediaCodec; protected MediaCodec mMediaCodec;
private ByteBuffer[] mInputBuffers; private ByteBuffer[] mInputBuffers;
...@@ -662,6 +665,98 @@ class MediaCodecBridge { ...@@ -662,6 +665,98 @@ class MediaCodecBridge {
} }
} }
// TODO(sandv): Use color space matrix when android has support for it.
@TargetApi(Build.VERSION_CODES.N)
@CalledByNative
private static void setColorSpace(MediaFormat format, final int primaries, final int transfer,
final int matrix, final int range) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
Log.e(TAG, "HDR is not support before Android N");
return;
}
// media/base/video_color_space.h
int colorStandard = -1;
switch (primaries) {
case 1:
colorStandard = MediaFormat.COLOR_STANDARD_BT709;
break;
case 4: // BT.470M.
case 5: // BT.470BG.
case 6: // SMPTE 170M.
case 7: // SMPTE 240M.
colorStandard = MediaFormat.COLOR_STANDARD_BT601_NTSC;
break;
case 9:
colorStandard = MediaFormat.COLOR_STANDARD_BT2020;
break;
}
if (colorStandard != -1) format.setInteger(MediaFormat.KEY_COLOR_STANDARD, colorStandard);
int colorTransfer = -1;
switch (transfer) {
case 1: // BT.709.
case 6: // SMPTE 170M.
case 7: // SMPTE 240M.
colorTransfer = MediaFormat.COLOR_TRANSFER_SDR_VIDEO;
break;
case 8:
colorTransfer = MediaFormat.COLOR_TRANSFER_LINEAR;
break;
case 16:
colorTransfer = MediaFormat.COLOR_TRANSFER_ST2084;
break;
case 18:
colorTransfer = MediaFormat.COLOR_TRANSFER_HLG;
break;
}
if (colorTransfer != -1) format.setInteger(MediaFormat.KEY_COLOR_TRANSFER, colorTransfer);
int colorRange = -1;
switch (range) {
case 1:
colorRange = MediaFormat.COLOR_RANGE_LIMITED;
break;
case 2:
colorRange = MediaFormat.COLOR_RANGE_FULL;
break;
}
if (colorRange != -1) format.setInteger(MediaFormat.KEY_COLOR_RANGE, colorRange);
}
@TargetApi(Build.VERSION_CODES.N)
@CalledByNative
private static void setHdrMatadata(MediaFormat format, float primaryRChromaticityX,
float primaryRChromaticityY, float primaryGChromaticityX, float primaryGChromaticityY,
float primaryBChromaticityX, float primaryBChromaticityY, float whitePointChromaticityX,
float whitePointChromaticityY, float maxMasteringLuminance, float minMasteringLuminance,
int maxContentLuminance, int maxFrameAverageLuminance) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
Log.e(TAG, "HDR not support before Android N");
return;
}
ByteBuffer hdrStaticInfo = ByteBuffer.wrap(new byte[25]);
hdrStaticInfo.order(ByteOrder.LITTLE_ENDIAN);
hdrStaticInfo.put((byte) 0); // Type.
hdrStaticInfo.putShort((short) ((primaryRChromaticityX * MAX_CHROMATICITY) + 0.5f));
hdrStaticInfo.putShort((short) ((primaryRChromaticityY * MAX_CHROMATICITY) + 0.5f));
hdrStaticInfo.putShort((short) ((primaryGChromaticityX * MAX_CHROMATICITY) + 0.5f));
hdrStaticInfo.putShort((short) ((primaryGChromaticityY * MAX_CHROMATICITY) + 0.5f));
hdrStaticInfo.putShort((short) ((primaryBChromaticityX * MAX_CHROMATICITY) + 0.5f));
hdrStaticInfo.putShort((short) ((primaryBChromaticityY * MAX_CHROMATICITY) + 0.5f));
hdrStaticInfo.putShort((short) ((whitePointChromaticityX * MAX_CHROMATICITY) + 0.5f));
hdrStaticInfo.putShort((short) ((whitePointChromaticityY * MAX_CHROMATICITY) + 0.5f));
hdrStaticInfo.putShort((short) (maxMasteringLuminance + 0.5f));
hdrStaticInfo.putShort((short) (minMasteringLuminance + 0.5f));
hdrStaticInfo.putShort((short) maxContentLuminance);
hdrStaticInfo.putShort((short) maxFrameAverageLuminance);
hdrStaticInfo.rewind();
format.setByteBuffer(MediaFormat.KEY_HDR_STATIC_INFO, hdrStaticInfo);
}
@TargetApi(Build.VERSION_CODES.M) @TargetApi(Build.VERSION_CODES.M)
@CalledByNative @CalledByNative
private boolean setSurface(Surface surface) { private boolean setSurface(Surface surface) {
......
...@@ -274,6 +274,26 @@ std::unique_ptr<MediaCodecBridge> MediaCodecBridgeImpl::CreateVideoDecoder( ...@@ -274,6 +274,26 @@ std::unique_ptr<MediaCodecBridge> MediaCodecBridgeImpl::CreateVideoDecoder(
Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, j_csd1); Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, j_csd1);
} }
if (hdr_metadata && hdr_metadata.has_value()) {
Java_MediaCodecBridge_setColorSpace(env, j_format,
static_cast<int>(color_space.primaries),
static_cast<int>(color_space.transfer),
static_cast<int>(color_space.matrix),
static_cast<int>(color_space.range));
const ::media::HDRMetadata& metadata = hdr_metadata.value();
const ::media::MasteringMetadata& mastering_metadata =
metadata.mastering_metadata;
Java_MediaCodecBridge_setHdrMatadata(
env, j_format, mastering_metadata.primary_r.x(),
mastering_metadata.primary_r.y(), mastering_metadata.primary_g.x(),
mastering_metadata.primary_g.y(), mastering_metadata.primary_b.x(),
mastering_metadata.primary_b.y(), mastering_metadata.white_point.x(),
mastering_metadata.white_point.y(), mastering_metadata.luminance_max,
mastering_metadata.luminance_min, metadata.max_content_light_level,
metadata.max_frame_average_light_level);
}
if (!Java_MediaCodecBridge_configureVideo(env, bridge->j_bridge_, j_format, if (!Java_MediaCodecBridge_configureVideo(env, bridge->j_bridge_, j_format,
surface, media_crypto, 0, surface, media_crypto, 0,
allow_adaptive_playback)) { allow_adaptive_playback)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment