Merge "CTS tests for dolby-vision MPEG4Extractor"
diff --git a/tests/tests/media/res/raw/video_dovi_1920x1080_30fps_dvhe_04.mp4 b/tests/tests/media/res/raw/video_dovi_1920x1080_30fps_dvhe_04.mp4
new file mode 100644
index 0000000..58f0f5b
--- /dev/null
+++ b/tests/tests/media/res/raw/video_dovi_1920x1080_30fps_dvhe_04.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_dovi_1920x1080_60fps_dvav_09.mp4 b/tests/tests/media/res/raw/video_dovi_1920x1080_60fps_dvav_09.mp4
new file mode 100755
index 0000000..0c754d6
--- /dev/null
+++ b/tests/tests/media/res/raw/video_dovi_1920x1080_60fps_dvav_09.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_dovi_1920x1080_60fps_dvhe_05.mp4 b/tests/tests/media/res/raw/video_dovi_1920x1080_60fps_dvhe_05.mp4
new file mode 100644
index 0000000..894f308
--- /dev/null
+++ b/tests/tests/media/res/raw/video_dovi_1920x1080_60fps_dvhe_05.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_dovi_1920x1080_60fps_dvhe_08.mp4 b/tests/tests/media/res/raw/video_dovi_1920x1080_60fps_dvhe_08.mp4
new file mode 100755
index 0000000..9cc7925
--- /dev/null
+++ b/tests/tests/media/res/raw/video_dovi_1920x1080_60fps_dvhe_08.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
index 67de797..78e22d5 100644
--- a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
@@ -23,9 +23,11 @@
 import android.icu.util.ULocale;
 import android.media.AudioFormat;
 import android.media.AudioPresentation;
+import android.media.MediaCodecInfo;
 import android.media.MediaDataSource;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
+import static android.media.MediaFormat.MIMETYPE_VIDEO_DOLBY_VISION;
 import android.media.cts.R;
 import android.os.PersistableBundle;
 import android.platform.test.annotations.AppModeFull;
@@ -35,6 +37,8 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.compatibility.common.util.MediaUtils;
+
 import java.io.BufferedReader;
 import java.io.Closeable;
 import java.io.IOException;
@@ -130,6 +134,169 @@
         afd.close();
     }
 
+    // DolbyVisionMediaExtractor for profile-level (DvheDtr/Fhd30).
+    public void testDolbyVisionMediaExtractorProfileDvheDtr() throws Exception {
+        TestMediaDataSource dataSource = setDataSource(R.raw.video_dovi_1920x1080_30fps_dvhe_04);
+
+        assertTrue("There should be either 1 or 2 tracks",
+            0 < mExtractor.getTrackCount() && 3 > mExtractor.getTrackCount());
+
+        MediaFormat trackFormat = mExtractor.getTrackFormat(0);
+        int trackCountForDolbyVision = 1;
+
+        // Handle the case where there is a Dolby Vision extractor
+        // Note that it may or may not have a Dolby Vision Decoder
+        if (mExtractor.getTrackCount() == 2) {
+            if (trackFormat.getString(MediaFormat.KEY_MIME)
+                    .equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION)) {
+                trackFormat = mExtractor.getTrackFormat(1);
+                trackCountForDolbyVision = 0;
+            }
+        }
+
+        if (MediaUtils.hasDecoder(MIMETYPE_VIDEO_DOLBY_VISION)) {
+            assertEquals("There must be 2 tracks", 2, mExtractor.getTrackCount());
+
+            MediaFormat trackFormatForDolbyVision =
+                mExtractor.getTrackFormat(trackCountForDolbyVision);
+
+            final String mimeType = trackFormatForDolbyVision.getString(MediaFormat.KEY_MIME);
+            assertEquals("video/dolby-vision", mimeType);
+
+            int profile = trackFormatForDolbyVision.getInteger(MediaFormat.KEY_PROFILE);
+            assertEquals(MediaCodecInfo.CodecProfileLevel.DolbyVisionProfileDvheDtr, profile);
+
+            int level = trackFormatForDolbyVision.getInteger(MediaFormat.KEY_LEVEL);
+            assertEquals(MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelFhd30, level);
+
+            final int trackIdForDolbyVision =
+                trackFormatForDolbyVision.getInteger(MediaFormat.KEY_TRACK_ID);
+
+            final int trackIdForBackwardCompat = trackFormat.getInteger(MediaFormat.KEY_TRACK_ID);
+            assertEquals(trackIdForDolbyVision, trackIdForBackwardCompat);
+        }
+
+        // The backward-compatible track should have mime video/hevc
+        final String mimeType = trackFormat.getString(MediaFormat.KEY_MIME);
+        assertEquals("video/hevc", mimeType);
+    }
+
+    // DolbyVisionMediaExtractor for profile-level (DvheStn/Fhd60).
+    public void testDolbyVisionMediaExtractorProfileDvheStn() throws Exception {
+        TestMediaDataSource dataSource = setDataSource(R.raw.video_dovi_1920x1080_60fps_dvhe_05);
+
+        if (MediaUtils.hasDecoder(MIMETYPE_VIDEO_DOLBY_VISION)) {
+            // DvheStn exposes only a single non-backward compatible Dolby Vision HDR track.
+            assertEquals("There must be 1 track", 1, mExtractor.getTrackCount());
+            final MediaFormat trackFormat = mExtractor.getTrackFormat(0);
+
+            final String mimeType = trackFormat.getString(MediaFormat.KEY_MIME);
+            assertEquals("video/dolby-vision", mimeType);
+
+            final int profile = trackFormat.getInteger(MediaFormat.KEY_PROFILE);
+            assertEquals(MediaCodecInfo.CodecProfileLevel.DolbyVisionProfileDvheStn, profile);
+
+            final int level = trackFormat.getInteger(MediaFormat.KEY_LEVEL);
+            assertEquals(MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelFhd60, level);
+        } else {
+            MediaUtils.skipTest("Device does not provide a Dolby Vision decoder");
+        }
+    }
+
+    // DolbyVisionMediaExtractor for profile-level (DvheSt/Fhd60).
+    public void testDolbyVisionMediaExtractorProfileDvheSt() throws Exception {
+        TestMediaDataSource dataSource = setDataSource(R.raw.video_dovi_1920x1080_60fps_dvhe_08);
+
+        assertTrue("There should be either 1 or 2 tracks",
+            0 < mExtractor.getTrackCount() && 3 > mExtractor.getTrackCount());
+
+        MediaFormat trackFormat = mExtractor.getTrackFormat(0);
+        int trackCountForDolbyVision = 1;
+
+        // Handle the case where there is a Dolby Vision extractor
+        // Note that it may or may not have a Dolby Vision Decoder
+        if (mExtractor.getTrackCount() == 2) {
+            if (trackFormat.getString(MediaFormat.KEY_MIME)
+                    .equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION)) {
+                trackFormat = mExtractor.getTrackFormat(1);
+                trackCountForDolbyVision = 0;
+            }
+        }
+
+        if (MediaUtils.hasDecoder(MIMETYPE_VIDEO_DOLBY_VISION)) {
+            assertEquals("There must be 2 tracks", 2, mExtractor.getTrackCount());
+
+            MediaFormat trackFormatForDolbyVision =
+                mExtractor.getTrackFormat(trackCountForDolbyVision);
+
+            final String mimeType = trackFormatForDolbyVision.getString(MediaFormat.KEY_MIME);
+            assertEquals("video/dolby-vision", mimeType);
+
+            int profile = trackFormatForDolbyVision.getInteger(MediaFormat.KEY_PROFILE);
+            assertEquals(MediaCodecInfo.CodecProfileLevel.DolbyVisionProfileDvheSt, profile);
+
+            int level = trackFormatForDolbyVision.getInteger(MediaFormat.KEY_LEVEL);
+            assertEquals(MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelFhd60, level);
+
+            final int trackIdForDolbyVision =
+                trackFormatForDolbyVision.getInteger(MediaFormat.KEY_TRACK_ID);
+
+            final int trackIdForBackwardCompat = trackFormat.getInteger(MediaFormat.KEY_TRACK_ID);
+            assertEquals(trackIdForDolbyVision, trackIdForBackwardCompat);
+        }
+
+        // The backward-compatible track should have mime video/hevc
+        final String mimeType = trackFormat.getString(MediaFormat.KEY_MIME);
+        assertEquals("video/hevc", mimeType);
+    }
+
+    // DolbyVisionMediaExtractor for profile-level (DvavSe/Fhd60).
+    public void testDolbyVisionMediaExtractorProfileDvavSe() throws Exception {
+        TestMediaDataSource dataSource = setDataSource(R.raw.video_dovi_1920x1080_60fps_dvav_09);
+
+        assertTrue("There should be either 1 or 2 tracks",
+            0 < mExtractor.getTrackCount() && 3 > mExtractor.getTrackCount());
+
+        MediaFormat trackFormat = mExtractor.getTrackFormat(0);
+        int trackCountForDolbyVision = 1;
+
+        // Handle the case where there is a Dolby Vision extractor
+        // Note that it may or may not have a Dolby Vision Decoder
+        if (mExtractor.getTrackCount() == 2) {
+            if (trackFormat.getString(MediaFormat.KEY_MIME)
+                    .equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION)) {
+                trackFormat = mExtractor.getTrackFormat(1);
+                trackCountForDolbyVision = 0;
+            }
+        }
+
+        if (MediaUtils.hasDecoder(MIMETYPE_VIDEO_DOLBY_VISION)) {
+            assertEquals("There must be 2 tracks", 2, mExtractor.getTrackCount());
+
+            MediaFormat trackFormatForDolbyVision =
+                mExtractor.getTrackFormat(trackCountForDolbyVision);
+
+            final String mimeType = trackFormatForDolbyVision.getString(MediaFormat.KEY_MIME);
+            assertEquals("video/dolby-vision", mimeType);
+
+            int profile = trackFormatForDolbyVision.getInteger(MediaFormat.KEY_PROFILE);
+            assertEquals(MediaCodecInfo.CodecProfileLevel.DolbyVisionProfileDvavSe, profile);
+
+            int level = trackFormatForDolbyVision.getInteger(MediaFormat.KEY_LEVEL);
+            assertEquals(MediaCodecInfo.CodecProfileLevel.DolbyVisionLevelFhd60, level);
+
+            final int trackIdForDolbyVision =
+                trackFormatForDolbyVision.getInteger(MediaFormat.KEY_TRACK_ID);
+
+            final int trackIdForBackwardCompat = trackFormat.getInteger(MediaFormat.KEY_TRACK_ID);
+            assertEquals(trackIdForDolbyVision, trackIdForBackwardCompat);
+        }
+
+        // The backward-compatible track should have mime video/avc
+        final String mimeType = trackFormat.getString(MediaFormat.KEY_MIME);
+        assertEquals("video/avc", mimeType);
+    }
+
     private void checkExtractorSamplesAndMetrics() {
         // 1MB is enough for any sample.
         final ByteBuffer buf = ByteBuffer.allocate(1024*1024);