19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.mediaframeworktest.stress; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1920a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.mediaframeworktest.MediaFrameworkTest; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22f16da13585ac22bb8d8fe7538509c2726bb06f29Yu Shan Emily Lauimport java.io.BufferedWriter; 23f16da13585ac22bb8d8fe7538509c2726bb06f29Yu Shan Emily Lauimport java.io.File; 24f16da13585ac22bb8d8fe7538509c2726bb06f29Yu Shan Emily Lauimport java.io.FileWriter; 2527c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchiimport java.io.IOException; 26f16da13585ac22bb8d8fe7538509c2726bb06f29Yu Shan Emily Lauimport java.io.Writer; 2779a3981e3885b9144bb3d458682141eed7365939Jeff Brownimport java.util.concurrent.Semaphore; 2879a3981e3885b9144bb3d458682141eed7365939Jeff Brownimport java.util.concurrent.TimeUnit; 29f16da13585ac22bb8d8fe7538509c2726bb06f29Yu Shan Emily Lau 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.hardware.Camera; 3127c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchiimport android.media.CamcorderProfile; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.media.MediaPlayer; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.media.MediaRecorder; 34ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchiimport android.os.Environment; 3579a3981e3885b9144bb3d458682141eed7365939Jeff Brownimport android.os.Handler; 3620a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lauimport android.os.Looper; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.ActivityInstrumentationTestCase2; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.suitebuilder.annotation.LargeTest; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.SurfaceHolder; 4148584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lauimport com.android.mediaframeworktest.MediaRecorderStressTestRunner; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Junit / Instrumentation test case for the media player api 4527c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi */ 4627c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchipublic class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> { 4727c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String TAG = "MediaRecorderStressTest"; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MediaRecorder mRecorder; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Camera mCamera; 5127c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi 52ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi private static final int CAMERA_ID = 0; 53984505d8168713469fb36bb50da50a2638751122Yu Shan Emily Lau private static final int NUMBER_OF_TIME_LAPSE_LOOPS = 1; 54984505d8168713469fb36bb50da50a2638751122Yu Shan Emily Lau private static final int TIME_LAPSE_PLAYBACK_WAIT_TIME = 30 * 1000; // 30 seconds 55ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi private static final int USE_TEST_RUNNER_PROFILE = -1; 56ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String OUTPUT_FILE_EXT = ".3gp"; 58ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi private static final String MEDIA_STRESS_OUTPUT = "mediaStressOutput.txt"; 59e35b3e052dab756113304cb394980e9f271b1613Yu Shan Emily Lau 6020a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback(); 6120a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau private final RecorderErrorCallback mRecorderErrorCallback = new RecorderErrorCallback(); 6220a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau 6379a3981e3885b9144bb3d458682141eed7365939Jeff Brown private Handler mHandler; 64ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi private Thread mLooperThread; 65ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi private Writer mOutput; 6679a3981e3885b9144bb3d458682141eed7365939Jeff Brown 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MediaRecorderStressTest() { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("com.android.mediaframeworktest", MediaFrameworkTest.class); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void setUp() throws Exception { 7279a3981e3885b9144bb3d458682141eed7365939Jeff Brown final Semaphore sem = new Semaphore(0); 7379a3981e3885b9144bb3d458682141eed7365939Jeff Brown mLooperThread = new Thread() { 7479a3981e3885b9144bb3d458682141eed7365939Jeff Brown @Override 7579a3981e3885b9144bb3d458682141eed7365939Jeff Brown public void run() { 7679a3981e3885b9144bb3d458682141eed7365939Jeff Brown Log.v(TAG, "starting looper"); 7779a3981e3885b9144bb3d458682141eed7365939Jeff Brown Looper.prepare(); 7879a3981e3885b9144bb3d458682141eed7365939Jeff Brown mHandler = new Handler(); 7979a3981e3885b9144bb3d458682141eed7365939Jeff Brown sem.release(); 8079a3981e3885b9144bb3d458682141eed7365939Jeff Brown Looper.loop(); 8179a3981e3885b9144bb3d458682141eed7365939Jeff Brown Log.v(TAG, "quit looper"); 8279a3981e3885b9144bb3d458682141eed7365939Jeff Brown } 8379a3981e3885b9144bb3d458682141eed7365939Jeff Brown }; 8479a3981e3885b9144bb3d458682141eed7365939Jeff Brown mLooperThread.start(); 8579a3981e3885b9144bb3d458682141eed7365939Jeff Brown if (! sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) { 8679a3981e3885b9144bb3d458682141eed7365939Jeff Brown fail("Failed to start the looper."); 8779a3981e3885b9144bb3d458682141eed7365939Jeff Brown } 88003a7569745640d700c318a463385ca5feb08728Yu Shan Emily Lau //Insert a 2 second before launching the test activity. This is 89003a7569745640d700c318a463385ca5feb08728Yu Shan Emily Lau //the workaround for the race condition of requesting the updated surface. 90003a7569745640d700c318a463385ca5feb08728Yu Shan Emily Lau Thread.sleep(2000); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getActivity(); 9279a3981e3885b9144bb3d458682141eed7365939Jeff Brown super.setUp(); 93ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 94ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi File stressOutFile = new File(String.format("%s/%s", 95ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Environment.getExternalStorageDirectory(), MEDIA_STRESS_OUTPUT)); 96ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput = new BufferedWriter(new FileWriter(stressOutFile, true)); 97ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write(this.getName() + "\n"); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9920a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau 10079a3981e3885b9144bb3d458682141eed7365939Jeff Brown @Override 10179a3981e3885b9144bb3d458682141eed7365939Jeff Brown protected void tearDown() throws Exception { 10279a3981e3885b9144bb3d458682141eed7365939Jeff Brown if (mHandler != null) { 10379a3981e3885b9144bb3d458682141eed7365939Jeff Brown mHandler.getLooper().quit(); 10479a3981e3885b9144bb3d458682141eed7365939Jeff Brown mHandler = null; 10579a3981e3885b9144bb3d458682141eed7365939Jeff Brown } 10679a3981e3885b9144bb3d458682141eed7365939Jeff Brown if (mLooperThread != null) { 10779a3981e3885b9144bb3d458682141eed7365939Jeff Brown mLooperThread.join(WAIT_TIMEOUT); 10879a3981e3885b9144bb3d458682141eed7365939Jeff Brown if (mLooperThread.isAlive()) { 10979a3981e3885b9144bb3d458682141eed7365939Jeff Brown fail("Failed to stop the looper."); 11020a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 11179a3981e3885b9144bb3d458682141eed7365939Jeff Brown mLooperThread = null; 11220a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 113ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write("\n\n"); 114ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.close(); 11579a3981e3885b9144bb3d458682141eed7365939Jeff Brown super.tearDown(); 11620a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 11720a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau 11879a3981e3885b9144bb3d458682141eed7365939Jeff Brown private void runOnLooper(final Runnable command) throws InterruptedException { 11979a3981e3885b9144bb3d458682141eed7365939Jeff Brown final Semaphore sem = new Semaphore(0); 12079a3981e3885b9144bb3d458682141eed7365939Jeff Brown mHandler.post(new Runnable() { 12120a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau @Override 12220a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau public void run() { 12379a3981e3885b9144bb3d458682141eed7365939Jeff Brown try { 12479a3981e3885b9144bb3d458682141eed7365939Jeff Brown command.run(); 12579a3981e3885b9144bb3d458682141eed7365939Jeff Brown } finally { 12679a3981e3885b9144bb3d458682141eed7365939Jeff Brown sem.release(); 12720a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 12820a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 12979a3981e3885b9144bb3d458682141eed7365939Jeff Brown }); 13079a3981e3885b9144bb3d458682141eed7365939Jeff Brown if (! sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) { 13179a3981e3885b9144bb3d458682141eed7365939Jeff Brown fail("Failed to run the command on the looper."); 13279a3981e3885b9144bb3d458682141eed7365939Jeff Brown } 13320a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 13420a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau 13579a3981e3885b9144bb3d458682141eed7365939Jeff Brown private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback { 13679a3981e3885b9144bb3d458682141eed7365939Jeff Brown public void onError(int error, android.hardware.Camera camera) { 137ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi fail(String.format("Camera error, code: %d", error)); 13820a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 13920a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 14020a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau 14179a3981e3885b9144bb3d458682141eed7365939Jeff Brown private final class RecorderErrorCallback implements MediaRecorder.OnErrorListener { 14279a3981e3885b9144bb3d458682141eed7365939Jeff Brown public void onError(MediaRecorder mr, int what, int extra) { 143ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi fail(String.format("Media recorder error, code: %d\textra: %d", what, extra)); 14420a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 14520a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 14620a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau 147ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi public void validateRecordedVideo(String recordedFile) { 14848584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau try { 14948584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau MediaPlayer mp = new MediaPlayer(); 150ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mp.setDataSource(recordedFile); 15148584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau mp.prepare(); 15248584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau int duration = mp.getDuration(); 15348584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau if (duration <= 0){ 154ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi fail("stressRecordAndPlayback"); 15548584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau } 15693aa00c664ae59c2224853f14d30a6671c467ef0Yu Shan Emily Lau mp.release(); 15748584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau } catch (Exception e) { 158ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi fail("stressRecordAndPlayback"); 15948584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau } 16048584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau } 16148584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau 162ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi public void removeRecordedVideo(String fileName){ 163ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi File video = new File(fileName); 164ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, "remove recorded video " + fileName); 16548584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau video.delete(); 16648584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau } 16748584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau 168ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi // Helper method for record & playback testing with different camcorder profiles 169ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi private void recordVideoAndPlayback(int profile) throws Exception { 170ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi int iterations; 171ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi int recordDuration; 172ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi boolean removeVideo; 173ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 174ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi int videoEncoder; 175ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi int audioEncoder; 176ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi int frameRate; 177ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi int videoWidth; 178ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi int videoHeight; 179ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi int bitRate; 180ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 181ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi if (profile != USE_TEST_RUNNER_PROFILE) { 182ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi assertTrue(String.format("Camera doesn't support profile %d", profile), 183ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi CamcorderProfile.hasProfile(CAMERA_ID, profile)); 184ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi CamcorderProfile camcorderProfile = CamcorderProfile.get(CAMERA_ID, profile); 185ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi videoEncoder = camcorderProfile.videoCodec; 186ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi audioEncoder = camcorderProfile.audioCodec; 187ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi frameRate = camcorderProfile.videoFrameRate; 188ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi videoWidth = camcorderProfile.videoFrameWidth; 189ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi videoHeight = camcorderProfile.videoFrameHeight; 190ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi bitRate = camcorderProfile.videoBitRate; 191ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } else { 192ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi videoEncoder = MediaRecorderStressTestRunner.mVideoEncoder; 193ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi audioEncoder = MediaRecorderStressTestRunner.mAudioEncoder; 194ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi frameRate = MediaRecorderStressTestRunner.mFrameRate; 195ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi videoWidth = MediaRecorderStressTestRunner.mVideoWidth; 196ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi videoHeight = MediaRecorderStressTestRunner.mVideoHeight; 197ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi bitRate = MediaRecorderStressTestRunner.mBitRate; 198ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } 199ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi iterations = MediaRecorderStressTestRunner.mIterations; 200ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi recordDuration = MediaRecorderStressTestRunner.mDuration; 201ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi removeVideo = MediaRecorderStressTestRunner.mRemoveVideo; 202ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 203ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 204ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write("Total number of loops: " + iterations + "\n"); 205ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 206f16da13585ac22bb8d8fe7538509c2726bb06f29Yu Shan Emily Lau try { 207ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write("No of loop: "); 208ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi for (int i = 0; i < iterations; i++) { 209ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi String fileName = String.format("%s/temp%d%s", 210ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Environment.getExternalStorageDirectory(), i, OUTPUT_FILE_EXT); 211ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, fileName); 212ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 21379a3981e3885b9144bb3d458682141eed7365939Jeff Brown runOnLooper(new Runnable() { 21479a3981e3885b9144bb3d458682141eed7365939Jeff Brown @Override 21579a3981e3885b9144bb3d458682141eed7365939Jeff Brown public void run() { 21679a3981e3885b9144bb3d458682141eed7365939Jeff Brown mRecorder = new MediaRecorder(); 21720a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 21879a3981e3885b9144bb3d458682141eed7365939Jeff Brown }); 219ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 22048584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau Log.v(TAG, "iterations : " + iterations); 221ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, "video encoder : " + videoEncoder); 222ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, "audio encoder : " + audioEncoder); 223ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, "frame rate : " + frameRate); 224ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, "video width : " + videoWidth); 225ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, "video height : " + videoHeight); 226ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, "bit rate : " + bitRate); 227ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, "record duration : " + recordDuration); 22848584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau 22920a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau mRecorder.setOnErrorListener(mRecorderErrorCallback); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 23220a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 233ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mRecorder.setOutputFile(fileName); 234ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mRecorder.setVideoFrameRate(frameRate); 235ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mRecorder.setVideoSize(videoWidth, videoHeight); 236ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mRecorder.setVideoEncoder(videoEncoder); 237ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mRecorder.setAudioEncoder(audioEncoder); 238ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mRecorder.setVideoEncodingBitRate(bitRate); 239ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "mediaRecorder setPreview"); 241ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mRecorder.setPreviewDisplay(surfaceHolder.getSurface()); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecorder.prepare(); 24320a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau mRecorder.start(); 244ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Thread.sleep(recordDuration); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "Before stop"); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecorder.stop(); 24779a3981e3885b9144bb3d458682141eed7365939Jeff Brown mRecorder.release(); 248ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //start the playback 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaPlayer mp = new MediaPlayer(); 251ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mp.setDataSource(fileName); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.prepare(); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.start(); 255ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Thread.sleep(recordDuration); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.release(); 257ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi validateRecordedVideo(fileName); 258ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi if (removeVideo) { 259ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi removeRecordedVideo(fileName); 260ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } 261ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi if (i == 0) { 262ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write(i + 1); 263ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } else { 264ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write(String.format(", %d", (i + 1))); 26548584d7b8f5e56b73bb13180bf6546b2647c1b28Yu Shan Emily Lau } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 268ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.e(TAG, e.toString()); 269ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi fail("Record and playback"); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 271ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } 272ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 273ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi // Record and playback stress test @ 1080P quality 274ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi @LargeTest 275ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi public void testStressRecordVideoAndPlayback1080P() throws Exception { 276ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi recordVideoAndPlayback(CamcorderProfile.QUALITY_1080P); 277ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } 278ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 279ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi // Record and playback stress test @ 720P quality 280ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi @LargeTest 281ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi public void testStressRecordVideoAndPlayback720P() throws Exception { 282ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi recordVideoAndPlayback(CamcorderProfile.QUALITY_720P); 283ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } 284ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 285ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi // Record and playback stress test @ 480P quality 286ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi @LargeTest 287ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi public void testStressRecordVideoAndPlayback480P() throws Exception { 288ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi recordVideoAndPlayback(CamcorderProfile.QUALITY_480P); 289ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } 290ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 291ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi // This test method uses the codec info from the test runner. Use this 292ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi // for more granular control of video encoding. 293ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi @LargeTest 294ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi public void defaultStressRecordVideoAndPlayback() throws Exception { 295ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi recordVideoAndPlayback(USE_TEST_RUNNER_PROFILE); 29620a6b955fe4ea5ba4025f16ba2da013df176c035Yu Shan Emily Lau } 29727c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi 29827c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi // Test case for stressing time lapse 29927c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi @LargeTest 30027c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi public void testStressTimeLapse() throws Exception { 30127c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi SurfaceHolder mSurfaceHolder; 30227c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 303ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi int recordDuration = MediaRecorderStressTestRunner.mTimeLapseDuration; 304ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi boolean removeVideo = MediaRecorderStressTestRunner.mRemoveVideo; 30527c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi double captureRate = MediaRecorderStressTestRunner.mCaptureRate; 306ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, "Start camera time lapse stress:"); 307ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write("Total number of loops: " + NUMBER_OF_TIME_LAPSE_LOOPS + "\n"); 30827c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi 30927c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi try { 310ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi for (int i = 0, n = Camera.getNumberOfCameras(); i < n; i++) { 311ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write("No of loop: camera " + i); 312ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi for (int j = 0; j < NUMBER_OF_TIME_LAPSE_LOOPS; j++) { 313ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi String fileName = String.format("%s/temp%d_%d%s", 314ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Environment.getExternalStorageDirectory(), i, j, OUTPUT_FILE_EXT); 315ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.v(TAG, fileName); 3167b996d19afcc7030400b515a665d28523a44bb18James Dong runOnLooper(new Runnable() { 3177b996d19afcc7030400b515a665d28523a44bb18James Dong @Override 3187b996d19afcc7030400b515a665d28523a44bb18James Dong public void run() { 3197b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder = new MediaRecorder(); 3207b996d19afcc7030400b515a665d28523a44bb18James Dong } 3217b996d19afcc7030400b515a665d28523a44bb18James Dong }); 3227b996d19afcc7030400b515a665d28523a44bb18James Dong 3237b996d19afcc7030400b515a665d28523a44bb18James Dong // Set callback 3247b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder.setOnErrorListener(mRecorderErrorCallback); 3257b996d19afcc7030400b515a665d28523a44bb18James Dong 3267b996d19afcc7030400b515a665d28523a44bb18James Dong // Set video source 3277b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 3287b996d19afcc7030400b515a665d28523a44bb18James Dong 3297b996d19afcc7030400b515a665d28523a44bb18James Dong // Set camcorder profile for time lapse 3307b996d19afcc7030400b515a665d28523a44bb18James Dong CamcorderProfile profile = 3317b996d19afcc7030400b515a665d28523a44bb18James Dong CamcorderProfile.get(j, CamcorderProfile.QUALITY_TIME_LAPSE_HIGH); 3327b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder.setProfile(profile); 3337b996d19afcc7030400b515a665d28523a44bb18James Dong 334ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi // Set the timelapse setting; 0.1 = 10 sec timelapse, 0.5 = 2 sec timelapse, etc 3357b996d19afcc7030400b515a665d28523a44bb18James Dong // http://developer.android.com/guide/topics/media/camera.html#time-lapse-video 3367b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder.setCaptureRate(captureRate); 3377b996d19afcc7030400b515a665d28523a44bb18James Dong 3387b996d19afcc7030400b515a665d28523a44bb18James Dong // Set output file 339ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mRecorder.setOutputFile(fileName); 3407b996d19afcc7030400b515a665d28523a44bb18James Dong 3417b996d19afcc7030400b515a665d28523a44bb18James Dong // Set the preview display 3427b996d19afcc7030400b515a665d28523a44bb18James Dong Log.v(TAG, "mediaRecorder setPreviewDisplay"); 3437b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 3447b996d19afcc7030400b515a665d28523a44bb18James Dong 3457b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder.prepare(); 3467b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder.start(); 347ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Thread.sleep(recordDuration); 3487b996d19afcc7030400b515a665d28523a44bb18James Dong Log.v(TAG, "Before stop"); 3497b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder.stop(); 3507b996d19afcc7030400b515a665d28523a44bb18James Dong mRecorder.release(); 3517b996d19afcc7030400b515a665d28523a44bb18James Dong 3527b996d19afcc7030400b515a665d28523a44bb18James Dong // Start the playback 3537b996d19afcc7030400b515a665d28523a44bb18James Dong MediaPlayer mp = new MediaPlayer(); 354ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mp.setDataSource(fileName); 3557b996d19afcc7030400b515a665d28523a44bb18James Dong mp.setDisplay(mSurfaceHolder); 3567b996d19afcc7030400b515a665d28523a44bb18James Dong mp.prepare(); 3577b996d19afcc7030400b515a665d28523a44bb18James Dong mp.start(); 3587b996d19afcc7030400b515a665d28523a44bb18James Dong Thread.sleep(TIME_LAPSE_PLAYBACK_WAIT_TIME); 3597b996d19afcc7030400b515a665d28523a44bb18James Dong mp.release(); 360ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi validateRecordedVideo(fileName); 361ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi if (removeVideo) { 362ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi removeRecordedVideo(fileName); 363ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } 364ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi 365ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi if (j == 0) { 366ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write(j + 1); 367ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } else { 368ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi mOutput.write(String.format(", %d", (j + 1))); 36927c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi } 37027c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi } 37127c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi } 372ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } catch (IllegalStateException e) { 373ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.e(TAG, e.toString()); 374ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi fail("Camera time lapse stress test IllegalStateException"); 375ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } catch (IOException e) { 376ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.e(TAG, e.toString()); 377ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi fail("Camera time lapse stress test IOException"); 378ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi } catch (Exception e) { 379ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi Log.e(TAG, e.toString()); 380ca6a5eee8f72742298d28d8a4b8e1bd32020a237Jason Noguchi fail("Camera time lapse stress test Exception"); 38127c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi } 38227c8d9ba169aa85127fac65d6df25e4335ee2fcaJason Noguchi } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 384