Roll android_tools support library to 25.1.0
[android_tools.git] / sdk / sources / android-23 / com / android / mediaframeworktest / performance / MediaPlayerPerformance.java
blobc52816571ffba36a44748c4be879523f2f8f4328
1 /*
2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
17 package com.android.mediaframeworktest.performance;
19 import com.android.mediaframeworktest.MediaFrameworkTest;
20 import com.android.mediaframeworktest.MediaFrameworkPerfTestRunner;
21 import com.android.mediaframeworktest.MediaNames;
22 import com.android.mediaframeworktest.MediaTestUtil;
24 import android.database.sqlite.SQLiteDatabase;
25 import android.hardware.Camera;
26 import android.hardware.Camera.PreviewCallback;
27 import android.media.CamcorderProfile;
28 import android.media.MediaPlayer;
29 import android.media.MediaRecorder;
30 import android.media.EncoderCapabilities.VideoEncoderCap;
31 import android.os.ConditionVariable;
32 import android.os.Looper;
33 import android.test.ActivityInstrumentationTestCase2;
34 import android.test.suitebuilder.annotation.LargeTest;
35 import android.util.Log;
36 import android.view.SurfaceHolder;
38 import java.util.List;
39 import java.io.BufferedReader;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.io.InputStreamReader;
43 import java.io.Writer;
44 import java.io.File;
45 import java.io.FileWriter;
46 import java.io.BufferedWriter;
48 import com.android.mediaframeworktest.MediaProfileReader;
50 /**
51 * Junit / Instrumentation - performance measurement for media player and
52 * recorder
54 * FIXME:
55 * Add tests on H264 video encoder
57 public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
59 private String TAG = "MediaPlayerPerformance";
61 private SurfaceHolder mSurfaceHolder = null;
62 private static final int NUM_STRESS_LOOP = 10;
63 private static final int NUM_PLAYBACk_IN_EACH_LOOP = 20;
64 private static final int SHORT_WAIT = 2 * 1000; // 2 seconds
65 private static final long MEDIA_STRESS_WAIT_TIME = 5000; //5 seconds
66 private static final String MEDIA_MEMORY_OUTPUT =
67 "/sdcard/mediaMemOutput.txt";
68 private static final String MEDIA_PROCMEM_OUTPUT =
69 "/sdcard/mediaProcmemOutput.txt";
70 private static final int CAMERA_ID = 0;
72 private static int mStartMemory = 0;
73 private static int mEndMemory = 0;
74 private static int mStartPid = 0;
75 private static int mEndPid = 0;
77 private Looper mLooper = null;
78 private RawPreviewCallback mRawPreviewCallback = new RawPreviewCallback();
79 private final ConditionVariable mPreviewDone = new ConditionVariable();
80 private static int WAIT_FOR_COMMAND_TO_COMPLETE = 10000; // Milliseconds.
82 //the tolerant memory leak
83 private static int ENCODER_LIMIT = 150;
84 private static int DECODER_LIMIT = 150;
85 private static int CAMERA_LIMIT = 80;
87 private Writer mProcMemWriter;
88 private Writer mMemWriter;
90 private CamcorderProfile mCamcorderProfile;
91 private int mVideoWidth;
92 private int mVideoHeight;
94 Camera mCamera;
96 public MediaPlayerPerformance() {
97 super("com.android.mediaframeworktest", MediaFrameworkTest.class);
100 @Override
101 protected void setUp() throws Exception {
102 super.setUp();
103 //Insert a 2 second before launching the test activity. This is
104 //the workaround for the race condition of requesting the updated surface.
105 Thread.sleep(SHORT_WAIT);
106 getActivity();
107 //Check if the device support the camcorder
108 mCamcorderProfile = CamcorderProfile.get(CAMERA_ID);
109 if (mCamcorderProfile != null) {
110 mVideoWidth = mCamcorderProfile.videoFrameWidth;
111 mVideoHeight = mCamcorderProfile.videoFrameHeight;
112 Log.v(TAG, "height = " + mVideoHeight + " width= " + mVideoWidth);
114 if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump)
115 MediaTestUtil.getNativeHeapDump(this.getName() + "_before");
117 if (MediaFrameworkPerfTestRunner.mGetProcmem) {
118 mProcMemWriter = new BufferedWriter(new FileWriter
119 (new File(MEDIA_PROCMEM_OUTPUT), true));
120 mProcMemWriter.write(this.getName() + "\n");
122 mMemWriter = new BufferedWriter(new FileWriter
123 (new File(MEDIA_MEMORY_OUTPUT), true));
124 mMemWriter.write(this.getName() + "\n");
127 @Override
128 protected void tearDown() throws Exception {
129 if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump)
130 MediaTestUtil.getNativeHeapDump(this.getName() + "_after");
132 if (MediaFrameworkPerfTestRunner.mGetProcmem) {
133 mProcMemWriter.close();
135 mMemWriter.write("\n");
136 mMemWriter.close();
137 super.tearDown();
140 private void initializeMessageLooper() {
141 final ConditionVariable startDone = new ConditionVariable();
142 new Thread() {
143 @Override
144 public void run() {
145 Looper.prepare();
146 Log.v(TAG, "start loopRun");
147 mLooper = Looper.myLooper();
148 mCamera = Camera.open(CAMERA_ID);
149 startDone.open();
150 Looper.loop();
151 Log.v(TAG, "initializeMessageLooper: quit.");
153 }.start();
155 if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
156 fail("initializeMessageLooper: start timeout");
160 private void terminateMessageLooper() throws Exception {
161 mLooper.quit();
162 // Looper.quit() is asynchronous. The looper may still has some
163 // preview callbacks in the queue after quit is called. The preview
164 // callback still uses the camera object (setHasPreviewCallback).
165 // After camera is released, RuntimeException will be thrown from
166 // the method. So we need to join the looper thread here.
167 mLooper.getThread().join();
168 mCamera.release();
171 private final class RawPreviewCallback implements PreviewCallback {
172 @Override
173 public void onPreviewFrame(byte[] rawData, Camera camera) {
174 mPreviewDone.open();
178 private void waitForPreviewDone() {
179 if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
180 Log.v(TAG, "waitForPreviewDone: timeout");
182 mPreviewDone.close();
185 public void stressCameraPreview() {
186 for (int i = 0; i < NUM_PLAYBACk_IN_EACH_LOOP; i++) {
187 try {
188 initializeMessageLooper();
189 mCamera.setPreviewCallback(mRawPreviewCallback);
190 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
191 mCamera.setPreviewDisplay(mSurfaceHolder);
192 mCamera.startPreview();
193 waitForPreviewDone();
194 Thread.sleep(1000);
195 mCamera.stopPreview();
196 terminateMessageLooper();
197 } catch (Exception e) {
198 Log.v(TAG, e.toString());
203 // Note: This test is to assume the mediaserver's pid is 34
204 public void mediaStressPlayback(String testFilePath) {
205 for (int i = 0; i < NUM_PLAYBACk_IN_EACH_LOOP; i++) {
206 MediaPlayer mp = new MediaPlayer();
207 try {
208 mp.setDataSource(testFilePath);
209 mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
210 mp.prepare();
211 mp.start();
212 Thread.sleep(MEDIA_STRESS_WAIT_TIME);
213 mp.release();
214 } catch (Exception e) {
215 mp.release();
216 Log.v(TAG, e.toString());
221 // Note: This test is to assume the mediaserver's pid is 34
222 private boolean stressVideoRecord(int frameRate, int width, int height, int videoFormat,
223 int outFormat, String outFile, boolean videoOnly) {
224 // Video recording
225 boolean doesTestFail = false;
226 for (int i = 0; i < NUM_PLAYBACk_IN_EACH_LOOP; i++) {
227 MediaRecorder mRecorder = new MediaRecorder();
228 try {
229 if (!videoOnly) {
230 Log.v(TAG, "setAudioSource");
231 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
233 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
234 mRecorder.setOutputFormat(outFormat);
235 Log.v(TAG, "output format " + outFormat);
236 mRecorder.setOutputFile(outFile);
237 mRecorder.setVideoFrameRate(frameRate);
238 mRecorder.setVideoSize(width, height);
239 Log.v(TAG, "setEncoder");
240 mRecorder.setVideoEncoder(videoFormat);
241 if (!videoOnly) {
242 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
244 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
245 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
246 mRecorder.prepare();
247 mRecorder.start();
248 Thread.sleep(MEDIA_STRESS_WAIT_TIME);
249 mRecorder.stop();
250 mRecorder.release();
251 //Insert 2 seconds to make sure the camera released.
252 Thread.sleep(SHORT_WAIT);
253 } catch (Exception e) {
254 Log.v("record video failed ", e.toString());
255 mRecorder.release();
256 doesTestFail = true;
257 break;
260 return !doesTestFail;
263 public void stressAudioRecord(String filePath) {
264 // This test is only for the short media file
265 for (int i = 0; i < NUM_PLAYBACk_IN_EACH_LOOP; i++) {
266 MediaRecorder mRecorder = new MediaRecorder();
267 try {
268 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
269 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
270 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
271 mRecorder.setOutputFile(filePath);
272 mRecorder.prepare();
273 mRecorder.start();
274 Thread.sleep(MEDIA_STRESS_WAIT_TIME);
275 mRecorder.stop();
276 mRecorder.release();
277 } catch (Exception e) {
278 Log.v(TAG, e.toString());
279 mRecorder.release();
284 //Write the ps output to the file
285 public void getMemoryWriteToLog(int writeCount) {
286 String memusage = null;
287 try {
288 if (writeCount == 0) {
289 mStartMemory = getMediaserverVsize();
290 mMemWriter.write("Start memory : " + mStartMemory + "\n");
292 memusage = captureMediaserverInfo();
293 mMemWriter.write(memusage);
294 if (writeCount == NUM_STRESS_LOOP - 1) {
295 mEndMemory = getMediaserverVsize();
296 mMemWriter.write("End Memory :" + mEndMemory + "\n");
298 } catch (Exception e) {
299 e.toString();
303 public void writeProcmemInfo() throws Exception {
304 if (MediaFrameworkPerfTestRunner.mGetProcmem) {
305 String cmd = "procmem " + getMediaserverPid();
306 Process p = Runtime.getRuntime().exec(cmd);
308 InputStream inStream = p.getInputStream();
309 InputStreamReader inReader = new InputStreamReader(inStream);
310 BufferedReader inBuffer = new BufferedReader(inReader);
311 String s;
312 while ((s = inBuffer.readLine()) != null) {
313 mProcMemWriter.write(s);
314 mProcMemWriter.write("\n");
316 mProcMemWriter.write("\n\n");
320 public String captureMediaserverInfo() {
321 String cm = "ps mediaserver";
322 String memoryUsage = null;
324 int ch;
325 try {
326 Process p = Runtime.getRuntime().exec(cm);
327 InputStream in = p.getInputStream();
328 StringBuffer sb = new StringBuffer(512);
329 while ((ch = in.read()) != -1) {
330 sb.append((char) ch);
332 memoryUsage = sb.toString();
333 } catch (IOException e) {
334 Log.v(TAG, e.toString());
336 String[] poList = memoryUsage.split("\r|\n|\r\n");
337 // A new media.log is enabled with ro.test_harness is set.
338 // The output of "ps mediaserver" will include the
339 // media.log process in the first line. Update the parsing
340 // to only read the thrid line.
341 // Smaple ps mediaserver output:
342 // USER PID PPID VSIZE RSS WCHAN PC NAME
343 // media 131 1 13676 4796 ffffffff 400b1bd0 S media.log
344 // media 219 131 37768 6892 ffffffff 400b236c S /system/bin/mediaserver
345 String memusage = poList[poList.length-1].concat("\n");
346 return memusage;
349 public int getMediaserverPid(){
350 String memoryUsage = null;
351 int pidvalue = 0;
352 memoryUsage = captureMediaserverInfo();
353 String[] poList2 = memoryUsage.split("\t|\\s+");
354 String pid = poList2[1];
355 pidvalue = Integer.parseInt(pid);
356 Log.v(TAG, "PID = " + pidvalue);
357 return pidvalue;
360 public int getMediaserverVsize(){
361 String memoryUsage = captureMediaserverInfo();
362 String[] poList2 = memoryUsage.split("\t|\\s+");
363 String vsize = poList2[3];
364 int vsizevalue = Integer.parseInt(vsize);
365 Log.v(TAG, "VSIZE = " + vsizevalue);
366 return vsizevalue;
369 public boolean validateMemoryResult(int startPid, int startMemory, int limit)
370 throws Exception {
371 // Wait for 10 seconds to make sure the memory settle.
372 Thread.sleep(10000);
373 mEndPid = getMediaserverPid();
374 int memDiff = mEndMemory - startMemory;
375 if (memDiff < 0) {
376 memDiff = 0;
378 mMemWriter.write("The total diff = " + memDiff);
379 mMemWriter.write("\n\n");
380 // mediaserver crash
381 if (startPid != mEndPid) {
382 mMemWriter.write("mediaserver died. Test failed\n");
383 return false;
385 // memory leak greter than the tolerant
386 if (memDiff > limit) return false;
387 return true;
390 // Test case 1: Capture the memory usage after every 20 h263 playback
391 @LargeTest
392 public void testH263VideoPlaybackMemoryUsage() throws Exception {
393 boolean memoryResult = false;
395 mStartPid = getMediaserverPid();
396 for (int i = 0; i < NUM_STRESS_LOOP; i++) {
397 mediaStressPlayback(MediaNames.VIDEO_HIGHRES_H263);
398 getMemoryWriteToLog(i);
399 writeProcmemInfo();
401 memoryResult = validateMemoryResult(mStartPid, mStartMemory, DECODER_LIMIT);
402 assertTrue("H263 playback memory test", memoryResult);
405 // Test case 2: Capture the memory usage after every 20 h264 playback
406 @LargeTest
407 public void testH264VideoPlaybackMemoryUsage() throws Exception {
408 boolean memoryResult = false;
410 mStartPid = getMediaserverPid();
411 for (int i = 0; i < NUM_STRESS_LOOP; i++) {
412 mediaStressPlayback(MediaNames.VIDEO_H264_AMR);
413 getMemoryWriteToLog(i);
414 writeProcmemInfo();
416 memoryResult = validateMemoryResult(mStartPid, mStartMemory, DECODER_LIMIT);
417 assertTrue("H264 playback memory test", memoryResult);
420 // Test case 3: Capture the memory usage after every 20 hevc playback
421 @LargeTest
422 public void testHEVCVideoPlaybackMemoryUsage() throws Exception {
423 boolean memoryResult = false;
425 mStartPid = getMediaserverPid();
426 for (int i = 0; i < NUM_STRESS_LOOP; i++) {
427 mediaStressPlayback(MediaNames.VIDEO_HEVC_AAC);
428 getMemoryWriteToLog(i);
429 writeProcmemInfo();
431 memoryResult = validateMemoryResult(mStartPid, mStartMemory, DECODER_LIMIT);
432 assertTrue("HEVC playback memory test", memoryResult);
435 // Test case 4: Capture the memory usage after every 20 mpeg2 playback
436 @LargeTest
437 public void testMPEG2VideoPlaybackMemoryUsage() throws Exception {
438 boolean memoryResult = false;
440 mStartPid = getMediaserverPid();
441 for (int i = 0; i < NUM_STRESS_LOOP; i++) {
442 mediaStressPlayback(MediaNames.VIDEO_MPEG2_AAC);
443 getMemoryWriteToLog(i);
444 writeProcmemInfo();
446 memoryResult = validateMemoryResult(mStartPid, mStartMemory, DECODER_LIMIT);
447 assertTrue("MPEG2 playback memory test", memoryResult);
450 // Test case 5: Capture the memory usage after every 20 video only recorded
451 @LargeTest
452 public void testH263RecordVideoOnlyMemoryUsage() throws Exception {
453 if (mCamcorderProfile != null) {
454 boolean memoryResult = false;
455 mStartPid = getMediaserverPid();
456 int frameRate = MediaProfileReader
457 .getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
458 assertTrue("H263 video recording frame rate", frameRate != -1);
459 for (int i = 0; i < NUM_STRESS_LOOP; i++) {
460 assertTrue(stressVideoRecord(frameRate, mVideoWidth, mVideoHeight,
461 MediaRecorder.VideoEncoder.H263, MediaRecorder.OutputFormat.MPEG_4,
462 MediaNames.RECORDED_VIDEO_3GP, true));
463 getMemoryWriteToLog(i);
464 writeProcmemInfo();
466 memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
467 assertTrue("H263 record only memory test", memoryResult);
471 // Test case 6: Capture the memory usage after every 20 video only recorded
472 @LargeTest
473 public void testMpeg4RecordVideoOnlyMemoryUsage() throws Exception {
474 if (mCamcorderProfile != null) {
475 boolean memoryResult = false;
476 mStartPid = getMediaserverPid();
477 int frameRate = MediaProfileReader.getMaxFrameRateForCodec
478 (MediaRecorder.VideoEncoder.MPEG_4_SP);
479 assertTrue("MPEG4 video recording frame rate", frameRate != -1);
480 for (int i = 0; i < NUM_STRESS_LOOP; i++) {
481 assertTrue(stressVideoRecord(frameRate, mVideoWidth, mVideoHeight,
482 MediaRecorder.VideoEncoder.MPEG_4_SP, MediaRecorder.OutputFormat.MPEG_4,
483 MediaNames.RECORDED_VIDEO_3GP, true));
484 getMemoryWriteToLog(i);
485 writeProcmemInfo();
487 memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
488 assertTrue("mpeg4 record only memory test", memoryResult);
492 // Test case 7: Capture the memory usage after every 20 video and audio
493 // recorded
494 @LargeTest
495 public void testRecordVideoAudioMemoryUsage() throws Exception {
496 if (mCamcorderProfile != null) {
497 boolean memoryResult = false;
498 mStartPid = getMediaserverPid();
499 int frameRate = MediaProfileReader
500 .getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
501 assertTrue("H263 video recording frame rate", frameRate != -1);
502 for (int i = 0; i < NUM_STRESS_LOOP; i++) {
503 assertTrue(stressVideoRecord(frameRate, mVideoWidth, mVideoHeight,
504 MediaRecorder.VideoEncoder.H263, MediaRecorder.OutputFormat.MPEG_4,
505 MediaNames.RECORDED_VIDEO_3GP, false));
506 getMemoryWriteToLog(i);
507 writeProcmemInfo();
509 memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
510 assertTrue("H263 audio video record memory test", memoryResult);
514 // Test case 8: Capture the memory usage after every 20 audio only recorded
515 @LargeTest
516 public void testRecordAudioOnlyMemoryUsage() throws Exception {
517 boolean memoryResult = false;
519 mStartPid = getMediaserverPid();
520 for (int i = 0; i < NUM_STRESS_LOOP; i++) {
521 stressAudioRecord(MediaNames.RECORDER_OUTPUT);
522 getMemoryWriteToLog(i);
523 writeProcmemInfo();
525 memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
526 assertTrue("audio record only memory test", memoryResult);
529 // Test case 9: Capture the memory usage after every 20 camera preview
530 @LargeTest
531 public void testCameraPreviewMemoryUsage() throws Exception {
532 boolean memoryResult = false;
534 mStartPid = getMediaserverPid();
535 for (int i = 0; i < NUM_STRESS_LOOP; i++) {
536 stressCameraPreview();
537 getMemoryWriteToLog(i);
538 writeProcmemInfo();
540 memoryResult = validateMemoryResult(mStartPid, mStartMemory, CAMERA_LIMIT);
541 assertTrue("camera preview memory test", memoryResult);