CodecTest.java revision b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.mediaframeworktest.functional; 18 19 20 21//import android.content.Resources; 22import com.android.mediaframeworktest.MediaFrameworkTest; 23import com.android.mediaframeworktest.MediaNames; 24 25import android.content.res.AssetFileDescriptor; 26import android.graphics.Bitmap; 27import android.graphics.BitmapFactory; 28import android.media.MediaMetadataRetriever; 29import android.media.MediaPlayer; 30import android.media.MediaRecorder; 31import android.os.Looper; 32import android.os.SystemClock; 33import android.util.Log; 34 35import java.io.IOException; 36import java.io.InputStream; 37/** 38 * Junit / Instrumentation test case for the media player api 39 40 */ 41public class CodecTest { 42 private static String TAG = "MediaPlayerApiTest"; 43 private static MediaPlayer mMediaPlayer; 44 private MediaPlayer.OnPreparedListener mOnPreparedListener; 45 46 private static int WAIT_FOR_COMMAND_TO_COMPLETE = 10000; //10 seconds max. 47 private static boolean mInitialized = false; 48 private static Looper mLooper = null; 49 private static final Object lock = new Object(); 50 private static final Object prepareDone = new Object(); 51 private static boolean onPrepareSuccess = false; 52 53 54 public static String printCpuInfo(){ 55 String cm = "dumpsys cpuinfo"; 56 String cpuinfo =null; 57 int ch; 58 try{ 59 Process p = Runtime.getRuntime().exec(cm); 60 InputStream in = p.getInputStream(); 61 StringBuffer sb = new StringBuffer(512); 62 while ( ( ch = in.read() ) != -1 ){ 63 sb.append((char) ch); 64 } 65 cpuinfo = sb.toString(); 66 }catch (IOException e){ 67 Log.v(TAG, e.toString()); 68 } 69 return cpuinfo; 70 } 71 72 73 public static int getDuration(String filePath) { 74 Log.v(TAG, "getDuration - " + filePath); 75 MediaPlayer mp = new MediaPlayer(); 76 try{ 77 mp.setDataSource(filePath); 78 mp.prepare(); 79 }catch (Exception e){} 80 int duration = mp.getDuration(); 81 Log.v(TAG, "Duration " + duration); 82 mp.release(); 83 Log.v(TAG, "release"); 84 return duration; 85 } 86 87 public static boolean getCurrentPosition(String filePath){ 88 Log.v(TAG, "GetCurrentPosition - " + filePath); 89 int currentPosition = 0; 90 long t1=0; 91 long t2 =0; 92 MediaPlayer mp = new MediaPlayer(); 93 try{ 94 mp.setDataSource(filePath); 95 Log.v(TAG, "start playback"); 96 mp.prepare(); 97 mp.start(); 98 t1=SystemClock.uptimeMillis(); 99 Thread.sleep(10000); 100 mp.pause(); 101 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 102 t2=SystemClock.uptimeMillis(); 103 }catch (Exception e){ 104 Log.v(TAG, e.toString()); 105 } 106 currentPosition = mp.getCurrentPosition(); 107 mp.stop(); 108 mp.release(); 109 Log.v(TAG, "mp currentPositon = " + currentPosition + " play duration = " + (t2-t1)); 110 //The currentposition should be within 10% of the sleep time 111 //For the very short mp3, it should return the length instead of 10 seconds 112 if (filePath.equals(MediaNames.SHORTMP3)){ 113 if (currentPosition < 1000 ) 114 return true; 115 } 116 if ((currentPosition < ((t2-t1) *1.2)) && (currentPosition > 0)) 117 return true; 118 else 119 return false; 120 } 121 122 public static boolean seekTo(String filePath){ 123 Log.v(TAG, "seekTo " + filePath); 124 int currentPosition = 0; 125 MediaPlayer mp = new MediaPlayer(); 126 try{ 127 mp.setDataSource(filePath); 128 mp.prepare(); 129 mp.start(); 130 mp.seekTo(MediaNames.SEEK_TIME); 131 Thread.sleep(MediaNames.WAIT_TIME); 132 currentPosition = mp.getCurrentPosition(); 133 }catch (Exception e){ 134 Log.v(TAG, e.getMessage()); 135 } 136 mp.stop(); 137 mp.release(); 138 Log.v(TAG, "CurrentPosition = " + currentPosition); 139 //The currentposition should be at least greater than the 80% of seek time 140 if ((currentPosition > MediaNames.SEEK_TIME *0.8)) 141 return true; 142 else 143 return false; 144 } 145 146 public static boolean setLooping(String filePath){ 147 int currentPosition = 0; 148 int duration = 0; 149 long t1 =0; 150 long t2 =0; 151 Log.v (TAG, "SetLooping - " + filePath); 152 MediaPlayer mp = new MediaPlayer(); 153 try{ 154 mp.setDataSource(filePath); 155 mp.prepare(); 156 duration = mp.getDuration(); 157 Log.v(TAG, "setLooping duration " + duration); 158 mp.setLooping(true); 159 mp.start(); 160 Thread.sleep(5000); 161 mp.seekTo(duration - 5000); 162 t1=SystemClock.uptimeMillis(); 163 Thread.sleep(20000); 164 t2=SystemClock.uptimeMillis(); 165 Log.v(TAG, "pause"); 166 //Bug# 1106852 - IllegalStateException will be thrown if pause is called 167 //in here 168 //mp.pause(); 169 currentPosition = mp.getCurrentPosition(); 170 Log.v(TAG, "looping position " + currentPosition + "duration = " + (t2-t1)); 171 }catch (Exception e){ 172 Log.v(TAG, "Exception : " + e.toString()); 173 } 174 mp.stop(); 175 mp.release(); 176 //The current position should be within 20% of the sleep time 177 //and should be greater than zero. 178 if ((currentPosition < ((t2-t1-5000)*1.2)) && currentPosition > 0) 179 return true; 180 else 181 return false; 182 } 183 184 public static boolean pause(String filePath) throws Exception { 185 Log.v(TAG, "pause - " + filePath); 186 boolean misPlaying = true; 187 boolean pauseResult = false; 188 long t1=0; 189 long t2=0; 190 MediaPlayer mp = new MediaPlayer(); 191 mp.setDataSource(filePath); 192 mp.prepare(); 193 int duration = mp.getDuration(); 194 mp.start(); 195 t1=SystemClock.uptimeMillis(); 196 Thread.sleep(5000); 197 mp.pause(); 198 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 199 t2=SystemClock.uptimeMillis(); 200 misPlaying = mp.isPlaying(); 201 int curPosition = mp.getCurrentPosition(); 202 Log.v(TAG, filePath + " pause currentPositon " + curPosition); 203 Log.v(TAG, "isPlaying "+ misPlaying + " wait time " + (t2 - t1) ); 204 String cpuinfo = printCpuInfo(); 205 Log.v(TAG, cpuinfo); 206 if ((curPosition>0) && (curPosition < ((t2-t1) * 1.3)) && (misPlaying == false)) 207 pauseResult = true; 208 mp.stop(); 209 mp.release(); 210 return pauseResult; 211 } 212 213 public static void prepareStopRelease(String filePath) throws Exception { 214 Log.v(TAG, "prepareStopRelease" + filePath); 215 MediaPlayer mp = new MediaPlayer(); 216 mp.setDataSource(filePath); 217 mp.prepare(); 218 mp.stop(); 219 mp.release(); 220 } 221 222 public static void preparePauseRelease(String filePath) throws Exception { 223 Log.v(TAG, "preparePauseRelease" + filePath); 224 MediaPlayer mp = new MediaPlayer(); 225 mp.setDataSource(filePath); 226 mp.prepare(); 227 mp.pause(); 228 mp.release(); 229 } 230 231 public static int videoHeight(String filePath) throws Exception { 232 Log.v(TAG, "videoHeight - " + filePath); 233 int videoHeight = 0; 234 MediaPlayer mp = new MediaPlayer(); 235 mp.setDataSource(filePath); 236 mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 237 mp.prepare(); 238 videoHeight = mp.getVideoHeight(); 239 mp.release(); 240 return videoHeight; 241 } 242 243 public static int videoWidth(String filePath) throws Exception { 244 Log.v(TAG, "videoWidth - " + filePath); 245 int videoWidth = 0; 246 MediaPlayer mp = new MediaPlayer(); 247 mp.setDataSource(filePath); 248 mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 249 mp.prepare(); 250 videoWidth = mp.getVideoWidth(); 251 mp.release(); 252 return videoWidth; 253 } 254 255 //This also test the streaming video which may take a long 256 //time to start the playback. 257 public static boolean videoSeekTo(String filePath) throws Exception { 258 Log.v(TAG, "videoSeekTo - " + filePath); 259 int currentPosition = 0; 260 int duration = 0; 261 boolean videoResult = false; 262 MediaPlayer mp = new MediaPlayer(); 263 mp.setDataSource(filePath); 264 mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 265 mp.prepare(); 266 mp.start(); 267 if (filePath.equals(MediaNames.VIDEO_SHORT_3GP)){ 268 mp.pause(); 269 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 270 mp.seekTo(0); 271 mp.start(); 272 Thread.sleep(1000); 273 currentPosition = mp.getCurrentPosition(); 274 Log.v(TAG,"short position " + currentPosition); 275 if (currentPosition > 100 ) 276 return true; 277 else 278 return false; 279 } 280 Thread.sleep(5000); 281 duration = mp.getDuration(); 282 Log.v(TAG, "video duration " + duration); 283 mp.pause(); 284 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 285 mp.seekTo(duration - 20000 ); 286 mp.start(); 287 Thread.sleep(1000); 288 mp.pause(); 289 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 290 mp.seekTo(duration/2); 291 mp.start(); 292 Thread.sleep(10000); 293 currentPosition = mp.getCurrentPosition(); 294 Log.v(TAG, "video currentPosition " + currentPosition); 295 mp.release(); 296 if (currentPosition > (duration /2 )*0.9) 297 return true; 298 else 299 return false; 300 301 } 302 303 public static boolean seekToEnd(String filePath){ 304 Log.v(TAG, "seekToEnd - " + filePath); 305 int duration = 0; 306 int currentPosition = 0; 307 boolean isPlaying = false; 308 MediaPlayer mp = new MediaPlayer(); 309 try{ 310 mp.setDataSource(filePath); 311 Log.v(TAG, "start playback"); 312 mp.prepare(); 313 duration = mp.getDuration(); 314 mp.seekTo(duration - 3000); 315 mp.start(); 316 Thread.sleep(6000); 317 }catch (Exception e){} 318 isPlaying = mp.isPlaying(); 319 currentPosition = mp.getCurrentPosition(); 320 Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying); 321 mp.stop(); 322 mp.release(); 323 Log.v(TAG, "duration = " + duration); 324 if (currentPosition < 0.9 * duration || isPlaying) 325 return false; 326 else 327 return true; 328 } 329 330 public static boolean shortMediaStop(String filePath){ 331 Log.v(TAG, "shortMediaStop - " + filePath); 332 //This test is only for the short media file 333 int duration = 0; 334 int currentPosition = 0; 335 boolean isPlaying = false; 336 MediaPlayer mp = new MediaPlayer(); 337 try{ 338 mp.setDataSource(filePath); 339 Log.v(TAG, "start playback"); 340 mp.prepare(); 341 duration = mp.getDuration(); 342 mp.start(); 343 Thread.sleep(10000); 344 }catch (Exception e){} 345 isPlaying = mp.isPlaying(); 346 currentPosition = mp.getCurrentPosition(); 347 Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying); 348 mp.stop(); 349 mp.release(); 350 Log.v(TAG, "duration = " + duration); 351 if (currentPosition > duration || isPlaying) 352 return false; 353 else 354 return true; 355 } 356 357 public static boolean playToEnd(String filePath){ 358 Log.v(TAG, "shortMediaStop - " + filePath); 359 //This test is only for the short media file 360 int duration = 200000; 361 int updateDuration = 0; 362 int currentPosition = 0; 363 boolean isPlaying = false; 364 MediaPlayer mp = new MediaPlayer(); 365 try{ 366 Thread.sleep(5000); 367 mp.setDataSource(filePath); 368 Log.v(TAG, "start playback"); 369 mp.prepare(); 370 //duration = mp.getDuration(); 371 mp.start(); 372 Thread.sleep(50000); 373 }catch (Exception e){} 374 isPlaying = mp.isPlaying(); 375 currentPosition = mp.getCurrentPosition(); 376 //updateDuration = mp.getDuration(); 377 Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying); 378 mp.stop(); 379 mp.release(); 380 //Log.v(TAG, "duration = " + duration); 381 //Log.v(TAG, "Update duration = " + updateDuration); 382 if (currentPosition > duration || isPlaying) 383 return false; 384 else 385 return true; 386 } 387 388 public static boolean seektoBeforeStart(String filePath){ 389 Log.v(TAG, "seektoBeforeStart - " + filePath); 390 //This test is only for the short media file 391 int duration = 0; 392 int currentPosition = 0; 393 394 MediaPlayer mp = new MediaPlayer(); 395 try{ 396 mp.setDataSource(filePath); 397 mp.prepare(); 398 duration = mp.getDuration(); 399 mp.seekTo(duration - 10000); 400 mp.start(); 401 currentPosition=mp.getCurrentPosition(); 402 mp.stop(); 403 mp.release(); 404 }catch (Exception e){} 405 if (currentPosition < duration/2) 406 return false; 407 else 408 return true; 409 } 410 411 public static boolean mediaRecorderRecord(String filePath){ 412 Log.v(TAG, "SoundRecording - " + filePath); 413 //This test is only for the short media file 414 int duration = 0; 415 try{ 416 MediaRecorder mRecorder = new MediaRecorder(); 417 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 418 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 419 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 420 mRecorder.setOutputFile(filePath); 421 mRecorder.prepare(); 422 mRecorder.start(); 423 Thread.sleep(500); 424 mRecorder.stop(); 425 Log.v(TAG, "sound recorded"); 426 mRecorder.release(); 427 }catch (Exception e){ 428 Log.v(TAG, e.toString()); 429 } 430 431 //Verify the recorded file 432 MediaPlayer mp = new MediaPlayer(); 433 try{ 434 mp.setDataSource(filePath); 435 mp.prepare(); 436 duration = mp.getDuration(); 437 Log.v(TAG,"Duration " + duration); 438 mp.release(); 439 }catch (Exception e){} 440 //Check the record media file length is greate than zero 441 if (duration > 0) 442 return true; 443 else 444 return false; 445 446 } 447 448 //Test for mediaMeta Data Thumbnail 449 public static boolean getThumbnail(String filePath, String goldenPath){ 450 Log.v(TAG, "getThumbnail - " + filePath); 451 452 int goldenHeight = 0; 453 int goldenWidth = 0; 454 int outputWidth = 0; 455 int outputHeight = 0; 456 457 //This test is only for the short media file 458 try{ 459 BitmapFactory mBitmapFactory = new BitmapFactory(); 460 461 MediaMetadataRetriever mMediaMetadataRetriever = new MediaMetadataRetriever(); 462 try { 463 mMediaMetadataRetriever.setDataSource(filePath); 464 } catch(Exception e) { 465 e.printStackTrace(); 466 return false; 467 } 468 Bitmap outThumbnail = mMediaMetadataRetriever.captureFrame(); 469 470 //Verify the thumbnail 471 Bitmap goldenBitmap = mBitmapFactory.decodeFile(goldenPath); 472 473 outputWidth = outThumbnail.getWidth(); 474 outputHeight = outThumbnail.getHeight(); 475 goldenHeight = goldenBitmap.getHeight(); 476 goldenWidth = goldenBitmap.getWidth(); 477 478 //check the image dimension 479 if ((outputWidth != goldenWidth) || (outputHeight != goldenHeight)) 480 return false; 481 482 //Check one line of pixel 483 int x = goldenHeight/2; 484 for (int j=0; j<goldenWidth; j++){ 485 if (goldenBitmap.getPixel(x, j) != outThumbnail.getPixel(x, j)){ 486 Log.v(TAG, "pixel = " + goldenBitmap.getPixel(x, j)); 487 return false; 488 } 489 } 490 }catch (Exception e){} 491 return true; 492 } 493 494 //Load midi file from resources 495 public static boolean resourcesPlayback(AssetFileDescriptor afd, int expectedDuration){ 496 int duration = 0; 497 try{ 498 MediaPlayer mp = new MediaPlayer(); 499 mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength()); 500 mp.prepare(); 501 mp.start(); 502 duration = mp.getDuration(); 503 Thread.sleep(5000); 504 mp.release(); 505 }catch (Exception e){ 506 Log.v(TAG,e.getMessage()); 507 } 508 if (duration > expectedDuration) 509 return true; 510 else 511 return false; 512 } 513 514 public static boolean prepareAsyncReset(String filePath){ 515 //preparesAsync 516 try{ 517 MediaPlayer mp = new MediaPlayer(); 518 mp.setDataSource(filePath); 519 mp.prepareAsync(); 520 mp.reset(); 521 mp.release(); 522 }catch (Exception e){ 523 Log.v(TAG,e.getMessage()); 524 return false; 525 } 526 return true; 527 } 528 529 530 public static boolean isLooping(String filePath) { 531 MediaPlayer mp = null; 532 533 try { 534 mp = new MediaPlayer(); 535 if (mp.isLooping()) { 536 Log.v(TAG, "MediaPlayer.isLooping() returned true after ctor"); 537 return false; 538 } 539 mp.setDataSource(filePath); 540 mp.prepare(); 541 542 mp.setLooping(true); 543 if (!mp.isLooping()) { 544 Log.v(TAG, "MediaPlayer.isLooping() returned false after setLooping(true)"); 545 return false; 546 } 547 548 mp.setLooping(false); 549 if (mp.isLooping()) { 550 Log.v(TAG, "MediaPlayer.isLooping() returned true after setLooping(false)"); 551 return false; 552 } 553 }catch (Exception e){ 554 Log.v(TAG, "Exception : " + e.toString()); 555 return false; 556 } finally { 557 if (mp != null) 558 mp.release(); 559 } 560 561 return true; 562 } 563 564 public static boolean isLoopingAfterReset(String filePath) { 565 MediaPlayer mp = null; 566 try { 567 mp = new MediaPlayer(); 568 mp.setDataSource(filePath); 569 mp.prepare(); 570 571 mp.setLooping(true); 572 mp.reset(); 573 if (mp.isLooping()) { 574 Log.v(TAG, "MediaPlayer.isLooping() returned true after reset()"); 575 return false; 576 } 577 }catch (Exception e){ 578 Log.v(TAG, "Exception : " + e.toString()); 579 return false; 580 } finally { 581 if (mp != null) 582 mp.release(); 583 } 584 585 return true; 586 } 587 588 /* 589 * Initializes the message looper so that the mediaPlayer object can 590 * receive the callback messages. 591 */ 592 private static void initializeMessageLooper() { 593 Log.v(TAG, "start looper"); 594 new Thread() { 595 @Override 596 public void run() { 597 // Set up a looper to be used by camera. 598 Looper.prepare(); 599 Log.v(TAG, "start loopRun"); 600 // Save the looper so that we can terminate this thread 601 // after we are done with it. 602 mLooper = Looper.myLooper(); 603 mMediaPlayer = new MediaPlayer(); 604 synchronized (lock) { 605 mInitialized = true; 606 lock.notify(); 607 } 608 Looper.loop(); // Blocks forever until Looper.quit() is called. 609 Log.v(TAG, "initializeMessageLooper: quit."); 610 } 611 }.start(); 612 } 613 614 /* 615 * Terminates the message looper thread. 616 */ 617 private static void terminateMessageLooper() { 618 mLooper.quit(); 619 mMediaPlayer.release(); 620 } 621 622 static MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() { 623 public void onPrepared(MediaPlayer mp) { 624 synchronized (prepareDone) { 625 Log.v(TAG, "notify the prepare callback"); 626 prepareDone.notify(); 627 onPrepareSuccess = true; 628 } 629 } 630 }; 631 632 public static boolean prepareAsyncCallback(String filePath) throws Exception { 633 int videoWidth = 0; 634 int videoHeight = 0; 635 boolean checkVideoDimension = false; 636 637 initializeMessageLooper(); 638 synchronized (lock) { 639 try { 640 lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE); 641 } catch(Exception e) { 642 Log.v(TAG, "looper was interrupted."); 643 return false; 644 } 645 } 646 try{ 647 mMediaPlayer.setOnPreparedListener(mPreparedListener); 648 mMediaPlayer.setDataSource(filePath); 649 mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 650 mMediaPlayer.prepareAsync(); 651 synchronized (prepareDone) { 652 try { 653 prepareDone.wait(WAIT_FOR_COMMAND_TO_COMPLETE); 654 Log.v(TAG, "setPreview done"); 655 } catch (Exception e) { 656 Log.v(TAG, "wait was interrupted."); 657 } 658 } 659 videoWidth = mMediaPlayer.getVideoWidth(); 660 videoHeight = mMediaPlayer.getVideoHeight(); 661 662 terminateMessageLooper(); 663 }catch (Exception e){ 664 Log.v(TAG,e.getMessage()); 665 } 666 return onPrepareSuccess; 667 } 668 669 670 671} 672 673