Commit e07b8fe7 by anjalibh Committed by Oliver Woodman

Parse ColorInfo from WebM Container and set it on MediaFormat.

* colorSpace, colorRange and colorTransfer are relevant to all videos.
* The rest of the fields are relevant only to HDR videos.
* Tested on a prototype device that decodes VP9 profile 2, 10 bit.
* The Webm spec spells color as 'colour' so the webm id reference use the same spelling.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=154098189
parent d3fe20cc
...@@ -29,6 +29,7 @@ import com.google.android.exoplayer2.metadata.id3.TextInformationFrame; ...@@ -29,6 +29,7 @@ import com.google.android.exoplayer2.metadata.id3.TextInformationFrame;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.ColorInfo;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
...@@ -61,11 +62,13 @@ public final class FormatTest extends TestCase { ...@@ -61,11 +62,13 @@ public final class FormatTest extends TestCase {
Metadata metadata = new Metadata( Metadata metadata = new Metadata(
new TextInformationFrame("id1", "description1", "value1"), new TextInformationFrame("id1", "description1", "value1"),
new TextInformationFrame("id2", "description2", "value2")); new TextInformationFrame("id2", "description2", "value2"));
ColorInfo colorInfo = new ColorInfo(C.COLOR_SPACE_BT709,
C.COLOR_RANGE_LIMITED, C.COLOR_TRANSFER_SDR, new byte[] {1, 2, 3, 4, 5, 6, 7});
Format formatToParcel = new Format("id", MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_H264, null, Format formatToParcel = new Format("id", MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_H264, null,
1024, 2048, 1920, 1080, 24, 90, 2, projectionData, C.STEREO_MODE_TOP_BOTTOM, 6, 44100, 1024, 2048, 1920, 1080, 24, 90, 2, projectionData, C.STEREO_MODE_TOP_BOTTOM, colorInfo, 6,
C.ENCODING_PCM_24BIT, 1001, 1002, 0, "und", Format.NO_VALUE, Format.OFFSET_SAMPLE_RELATIVE, 44100, C.ENCODING_PCM_24BIT, 1001, 1002, 0, "und", Format.NO_VALUE,
INIT_DATA, drmInitData, metadata); Format.OFFSET_SAMPLE_RELATIVE, INIT_DATA, drmInitData, metadata);
Parcel parcel = Parcel.obtain(); Parcel parcel = Parcel.obtain();
formatToParcel.writeToParcel(parcel, 0); formatToParcel.writeToParcel(parcel, 0);
......
...@@ -20,6 +20,7 @@ import android.content.Context; ...@@ -20,6 +20,7 @@ import android.content.Context;
import android.media.AudioFormat; import android.media.AudioFormat;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.media.MediaFormat;
import android.support.annotation.IntDef; import android.support.annotation.IntDef;
import android.view.Surface; import android.view.Surface;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
...@@ -555,6 +556,67 @@ public final class C { ...@@ -555,6 +556,67 @@ public final class C {
public static final int STEREO_MODE_STEREO_MESH = 3; public static final int STEREO_MODE_STEREO_MESH = 3;
/** /**
* Video colorspaces.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Format.NO_VALUE, COLOR_SPACE_BT709, COLOR_SPACE_BT601, COLOR_SPACE_BT2020})
public @interface ColorSpace {}
/**
* @see MediaFormat#COLOR_STANDARD_BT709
*/
@SuppressWarnings("InlinedApi")
public static final int COLOR_SPACE_BT709 = MediaFormat.COLOR_STANDARD_BT709;
/**
* @see MediaFormat#COLOR_STANDARD_BT601_PAL
*/
@SuppressWarnings("InlinedApi")
public static final int COLOR_SPACE_BT601 = MediaFormat.COLOR_STANDARD_BT601_PAL;
/**
* @see MediaFormat#COLOR_STANDARD_BT2020
*/
@SuppressWarnings("InlinedApi")
public static final int COLOR_SPACE_BT2020 = MediaFormat.COLOR_STANDARD_BT2020;
/**
* Video color transfer characteristics.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Format.NO_VALUE, COLOR_TRANSFER_SDR, COLOR_TRANSFER_ST2084, COLOR_TRANSFER_HLG})
public @interface ColorTransfer {}
/**
* @see MediaFormat#COLOR_TRANSFER_SDR_VIDEO
*/
@SuppressWarnings("InlinedApi")
public static final int COLOR_TRANSFER_SDR = MediaFormat.COLOR_TRANSFER_SDR_VIDEO;
/**
* @see MediaFormat#COLOR_TRANSFER_ST2084
*/
@SuppressWarnings("InlinedApi")
public static final int COLOR_TRANSFER_ST2084 = MediaFormat.COLOR_TRANSFER_ST2084;
/**
* @see MediaFormat#COLOR_TRANSFER_HLG
*/
@SuppressWarnings("InlinedApi")
public static final int COLOR_TRANSFER_HLG = MediaFormat.COLOR_TRANSFER_HLG;
/**
* Video color range.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Format.NO_VALUE, COLOR_RANGE_LIMITED, COLOR_RANGE_FULL})
public @interface ColorRange {}
/**
* @see MediaFormat#COLOR_RANGE_LIMITED
*/
@SuppressWarnings("InlinedApi")
public static final int COLOR_RANGE_LIMITED = MediaFormat.COLOR_RANGE_LIMITED;
/**
* @see MediaFormat#COLOR_RANGE_FULL
*/
@SuppressWarnings("InlinedApi")
public static final int COLOR_RANGE_FULL = MediaFormat.COLOR_RANGE_FULL;
/**
* Priority for media playback. * Priority for media playback.
* *
* <p>Larger values indicate higher priorities. * <p>Larger values indicate higher priorities.
......
...@@ -762,7 +762,7 @@ import java.util.List; ...@@ -762,7 +762,7 @@ import java.util.List;
out.format = Format.createVideoSampleFormat(Integer.toString(trackId), mimeType, null, out.format = Format.createVideoSampleFormat(Integer.toString(trackId), mimeType, null,
Format.NO_VALUE, Format.NO_VALUE, width, height, Format.NO_VALUE, initializationData, Format.NO_VALUE, Format.NO_VALUE, width, height, Format.NO_VALUE, initializationData,
rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, drmInitData); rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, null, drmInitData);
} }
/** /**
......
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.video;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import java.util.Arrays;
/**
* Stores color info.
*/
public final class ColorInfo implements Parcelable {
/**
* The color space of the video. Valid values are {@link C#COLOR_SPACE_BT601}, {@link
* C#COLOR_SPACE_BT709}, {@link C#COLOR_SPACE_BT2020} or {@link Format#NO_VALUE} if unknown.
*/
@C.ColorSpace
public final int colorSpace;
/**
* The color range of the video. Valid values are {@link C#COLOR_RANGE_LIMITED}, {@link
* C#COLOR_RANGE_FULL} or {@link Format#NO_VALUE} if unknown.
*/
@C.ColorRange
public final int colorRange;
/**
* The color transfer characteristicks of the video. Valid values are {@link
* C#COLOR_TRANSFER_HLG}, {@link C#COLOR_TRANSFER_ST2084}, {@link C#COLOR_TRANSFER_SDR} or {@link
* Format#NO_VALUE} if unknown.
*/
@C.ColorTransfer
public final int colorTransfer;
/**
* HdrStaticInfo as defined in CTA-861.3.
*/
public final byte[] hdrStaticInfo;
// Lazily initialized hashcode.
private int hashCode;
/**
* Constructs the ColorInfo.
*
* @param colorSpace The color space of the video.
* @param colorRange The color range of the video.
* @param colorTransfer The color transfer characteristics of the video.
* @param hdrStaticInfo HdrStaticInfo as defined in CTA-861.3.
*/
public ColorInfo(@C.ColorSpace int colorSpace, @C.ColorRange int colorRange,
@C.ColorTransfer int colorTransfer, byte[] hdrStaticInfo) {
this.colorSpace = colorSpace;
this.colorRange = colorRange;
this.colorTransfer = colorTransfer;
this.hdrStaticInfo = hdrStaticInfo;
}
@SuppressWarnings("ResourceType")
/* package */ ColorInfo(Parcel in) {
colorSpace = in.readInt();
colorRange = in.readInt();
colorTransfer = in.readInt();
boolean hasHdrStaticInfo = in.readInt() != 0;
hdrStaticInfo = hasHdrStaticInfo ? in.createByteArray() : null;
}
// Parcelable implementation.
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
ColorInfo other = (ColorInfo) obj;
if (colorSpace != other.colorSpace || colorRange != other.colorRange
|| colorTransfer != other.colorTransfer
|| !Arrays.equals(hdrStaticInfo, other.hdrStaticInfo)) {
return false;
}
return true;
}
@Override
public String toString() {
return "ColorInfo(" + colorSpace + ", " + colorRange + ", " + colorTransfer
+ ", " + (hdrStaticInfo != null) + ")";
}
@Override
public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 31 * result + colorSpace;
result = 31 * result + colorRange;
result = 31 * result + colorTransfer;
result = 31 * result + Arrays.hashCode(hdrStaticInfo);
hashCode = result;
}
return hashCode;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(colorSpace);
dest.writeInt(colorRange);
dest.writeInt(colorTransfer);
dest.writeInt(hdrStaticInfo != null ? 1 : 0);
if (hdrStaticInfo != null) {
dest.writeByteArray(hdrStaticInfo);
}
}
public static final Parcelable.Creator<ColorInfo> CREATOR = new Parcelable.Creator<ColorInfo>() {
@Override
public ColorInfo createFromParcel(Parcel in) {
return new ColorInfo(in);
}
@Override
public ColorInfo[] newArray(int size) {
return new ColorInfo[0];
}
};
}
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 sign in to comment