Adds CTS test case for timed text APIs into MediaPlayerTest.
Change-Id: I0f5584a0e8bd7834411e0c2de459ab27af197235
diff --git a/tests/tests/media/res/raw/test_subtitle1_srt.3gp b/tests/tests/media/res/raw/test_subtitle1_srt.3gp
new file mode 100644
index 0000000..8dbc240
--- /dev/null
+++ b/tests/tests/media/res/raw/test_subtitle1_srt.3gp
@@ -0,0 +1,39 @@
+1
+00:00:0,000 --> 00:00:0,500
+2:0000
+
+2
+00:00:1,000 --> 00:00:1,500
+2:1000
+
+3
+00:00:2,000 --> 00:00:2,500
+2:2000
+
+4
+00:00:3,000 --> 00:00:3,500
+2:3000
+
+5
+00:00:4,000 --> 00:00:4,500
+2:4000
+
+6
+00:00:5,000 --> 00:00:5,500
+2:5000
+
+7
+00:00:6,000 --> 00:00:6,500
+2:6000
+
+8
+00:00:7,000 --> 00:00:7,500
+2:7000
+
+9
+00:00:8,000 --> 00:00:8,500
+2:8000
+
+10
+00:00:9,000 --> 00:00:9,500
+2:9000
diff --git a/tests/tests/media/res/raw/test_subtitle2_srt.3gp b/tests/tests/media/res/raw/test_subtitle2_srt.3gp
new file mode 100644
index 0000000..7ac2e72
--- /dev/null
+++ b/tests/tests/media/res/raw/test_subtitle2_srt.3gp
@@ -0,0 +1,39 @@
+1
+00:00:0,500 --> 00:00:1,000
+3:500
+
+2
+00:00:1,500 --> 00:00:2,000
+3:1500
+
+3
+00:00:2,500 --> 00:00:3,000
+3:2500
+
+4
+00:00:3,500 --> 00:00:4,000
+3:3500
+
+5
+00:00:4,500 --> 00:00:5,000
+3:4500
+
+6
+00:00:5,500 --> 00:00:6,000
+3:5500
+
+7
+00:00:6,500 --> 00:00:7,000
+3:6500
+
+8
+00:00:7,500 --> 00:00:8,000
+3:7500
+
+9
+00:00:8,500 --> 00:00:9,000
+3:8500
+
+10
+00:00:9,500 --> 00:00:10,000
+3:9500
diff --git a/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp b/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp
new file mode 100644
index 0000000..1de14a5
--- /dev/null
+++ b/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 0c39531..d94f4ab 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -23,15 +23,19 @@
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
+import android.media.TimedText;
import android.media.audiofx.AudioEffect;
import android.media.audiofx.Visualizer;
import android.net.Uri;
import android.os.Environment;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.util.Log;
import java.io.File;
+import java.util.StringTokenizer;
import java.util.UUID;
+import java.util.Vector;
import java.util.concurrent.CountDownLatch;
/**
@@ -44,10 +48,63 @@
public class MediaPlayerTest extends MediaPlayerTestBase {
private String RECORDED_FILE;
+ private static final String LOG_TAG = "MediaPlayerTest";
private static final int RECORDED_VIDEO_WIDTH = 176;
private static final int RECORDED_VIDEO_HEIGHT = 144;
private static final long RECORDED_DURATION_MS = 3000;
+ private Vector<Integer> mTimedTextTrackIndex = new Vector<Integer>();
+
+ public class SubtitleMonitor {
+ private int selectedTrack;
+ private int numSignal;
+
+ public synchronized void reset() {
+ selectedTrack = 0;
+ numSignal = 0;
+ }
+
+ public synchronized void setSelectedTrack(int index) {
+ selectedTrack = index;
+ }
+
+ public synchronized int getSelectedTrack() {
+ return selectedTrack;
+ }
+
+ public synchronized void signal() {
+ numSignal++;
+ notifyAll();
+ }
+
+ public synchronized int getNumSignal() {
+ return numSignal;
+ }
+
+ public synchronized void waitForSignal(int targetCount) throws InterruptedException {
+ while (numSignal < targetCount) {
+ wait();
+ }
+ }
+
+ public synchronized void waitForSignal(int targetCount, long millis)
+ throws InterruptedException {
+ if (millis == 0) {
+ waitForSignal(targetCount);
+ return;
+ }
+ long deadline = System.currentTimeMillis() + millis;
+ while (numSignal < targetCount) {
+ long delay = deadline - System.currentTimeMillis();
+ if (delay < 0) {
+ return;
+ }
+ wait(delay);
+ }
+ }
+ }
+
+ private SubtitleMonitor mSubtitleStatus = new SubtitleMonitor();
private File mOutFile;
@@ -639,6 +696,99 @@
R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_stereo_128kbps_22050hz, 176, 144);
}
+ private void readTimedTextTracks() throws Exception {
+ mTimedTextTrackIndex.clear();
+ MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
+ if (trackInfos == null || trackInfos.length == 0) {
+ return;
+ }
+ for (int i = 0; i < trackInfos.length; ++i) {
+ if (trackInfos[i] == null) continue;
+ if (trackInfos[i].getTrackType() ==
+ MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
+ mTimedTextTrackIndex.add(i);
+ }
+ }
+ }
+
+ private int getTimedTextTrackCount() {
+ return mTimedTextTrackIndex.size();
+ }
+
+ private void selectSubtitleTrack(int index) throws Exception {
+ int trackIndex = mTimedTextTrackIndex.get(index);
+ mMediaPlayer.selectTrack(trackIndex);
+ mSubtitleStatus.setSelectedTrack(index);
+ }
+
+ public void testChangeSubtitleTrack() throws Exception {
+ loadResource(R.raw.testvideo_with_2_subtitles);
+ readTimedTextTracks();
+ assertEquals(getTimedTextTrackCount(), 2);
+
+ // Adds two more external subtitle files.
+ loadSubtitleSource(R.raw.test_subtitle1_srt);
+ loadSubtitleSource(R.raw.test_subtitle2_srt);
+ readTimedTextTracks();
+ assertEquals(getTimedTextTrackCount(), 4);
+
+ mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
+ mMediaPlayer.setScreenOnWhilePlaying(true);
+ mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+ mMediaPlayer.setOnTimedTextListener(new MediaPlayer.OnTimedTextListener() {
+ @Override
+ public void onTimedText(MediaPlayer mp, TimedText text) {
+ final int toleranceMs = 100;
+ final int durationMs = 500;
+ int posMs = mMediaPlayer.getCurrentPosition();
+ if (text != null) {
+ String plainText = text.getText();
+ if (plainText != null) {
+ StringTokenizer tokens = new StringTokenizer(plainText.trim(), ":");
+ int subtitleTrackIndex = Integer.parseInt(tokens.nextToken());
+ int startMs = Integer.parseInt(tokens.nextToken());
+ Log.w(LOG_TAG, "text: " + plainText.trim() +
+ ", trackId: " + subtitleTrackIndex + ", posMs: " + posMs);
+ assertTrue(posMs >= startMs - toleranceMs);
+ assertTrue(posMs < startMs + durationMs + toleranceMs);
+ assertEquals(mSubtitleStatus.getSelectedTrack(), subtitleTrackIndex);
+ mSubtitleStatus.signal();
+ }
+ }
+ }
+ });
+
+ mSubtitleStatus.reset();
+ selectSubtitleTrack(0);
+
+ mMediaPlayer.prepare();
+ assertFalse(mMediaPlayer.isPlaying());
+ mMediaPlayer.start();
+ assertTrue(mMediaPlayer.isPlaying());
+
+ // Waits until at least two subtitles are fired. Timeout is 2 sec.
+ // Please refer the test srt files:
+ // test_subtitle1_srt.3gp and test_subtitle2_srt.3gp
+ mSubtitleStatus.waitForSignal(2, 2000);
+ assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+ mSubtitleStatus.reset();
+
+ selectSubtitleTrack(1);
+ mSubtitleStatus.waitForSignal(2, 2000);
+ assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+ mSubtitleStatus.reset();
+
+ selectSubtitleTrack(2);
+ mSubtitleStatus.waitForSignal(2, 2000);
+ assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+ mSubtitleStatus.reset();
+
+ selectSubtitleTrack(3);
+ mSubtitleStatus.waitForSignal(2, 2000);
+ assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+ mMediaPlayer.stop();
+ }
+
public void testCallback() throws Throwable {
final int mp4Duration = 8484;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
index 8b9da47..1fc7929 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
@@ -137,6 +137,16 @@
}
}
+ protected void loadSubtitleSource(int resid) throws Exception {
+ AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+ try {
+ mMediaPlayer.addTimedTextSource(afd.getFileDescriptor(), afd.getStartOffset(),
+ afd.getLength(), MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP);
+ } finally {
+ afd.close();
+ }
+ }
+
protected void playLiveVideoTest(String path, int playTime) throws Exception {
playVideoWithRetries(path, null, null, playTime);
}