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 17 package com.android.mediaframeworktest.functional; 18 19 20 21 //import android.content.Resources; 22 import com.android.mediaframeworktest.MediaFrameworkTest; 23 import com.android.mediaframeworktest.MediaNames; 24 25 import android.content.res.AssetFileDescriptor; 26 import android.graphics.Bitmap; 27 import android.graphics.BitmapFactory; 28 import android.media.MediaCodecInfo; 29 import android.media.MediaCodecList; 30 import android.media.MediaExtractor; 31 import android.media.MediaFormat; 32 import android.media.MediaMetadataRetriever; 33 import android.media.MediaPlayer; 34 import android.media.MediaRecorder; 35 import android.os.Looper; 36 import android.os.SystemClock; 37 import android.util.Log; 38 39 import java.io.File; 40 import java.io.FileWriter; 41 import java.io.IOException; 42 import java.io.InputStream; 43 import java.io.OutputStream; 44 import java.io.Writer; 45 import java.io.FileOutputStream; 46 import java.util.HashSet; 47 import java.util.Random; 48 import java.util.Set; 49 /** 50 * Junit / Instrumentation test case for the media player api 51 52 */ 53 public class CodecTest { 54 private static String TAG = "CodecTest"; 55 private static MediaPlayer mMediaPlayer; 56 private MediaPlayer.OnPreparedListener mOnPreparedListener; 57 58 private static int WAIT_FOR_COMMAND_TO_COMPLETE = 60000; //1 min max. 59 private static boolean mInitialized = false; 60 private static boolean mPrepareReset = false; 61 private static Looper mLooper = null; 62 private static final Object lock = new Object(); 63 private static final Object prepareDone = new Object(); 64 private static final Object videoSizeChanged = new Object(); 65 private static final Object onCompletion = new Object(); 66 private static boolean onPrepareSuccess = false; 67 public static boolean onCompleteSuccess = false; 68 public static boolean mPlaybackError = false; 69 public static boolean mFailedToCompleteWithNoError = true; 70 public static int mMediaInfoUnknownCount = 0; 71 public static int mMediaInfoVideoTrackLaggingCount = 0; 72 public static int mMediaInfoBadInterleavingCount = 0; 73 public static int mMediaInfoNotSeekableCount = 0; 74 public static int mMediaInfoMetdataUpdateCount = 0; 75 private static Set<String> mSupportedTypes = new HashSet<>(); 76 printCpuInfo()77 public static String printCpuInfo(){ 78 String cm = "dumpsys cpuinfo"; 79 String cpuinfo =null; 80 int ch; 81 try{ 82 Process p = Runtime.getRuntime().exec(cm); 83 InputStream in = p.getInputStream(); 84 StringBuffer sb = new StringBuffer(512); 85 while ( ( ch = in.read() ) != -1 ){ 86 sb.append((char) ch); 87 } 88 cpuinfo = sb.toString(); 89 }catch (IOException e){ 90 Log.v(TAG, e.toString()); 91 } 92 return cpuinfo; 93 } 94 95 getDuration(String filePath)96 public static int getDuration(String filePath) { 97 Log.v(TAG, "getDuration - " + filePath); 98 MediaPlayer mp = new MediaPlayer(); 99 try{ 100 mp.setDataSource(filePath); 101 mp.prepare(); 102 }catch (Exception e){ 103 Log.v(TAG, e.toString()); 104 } 105 int duration = mp.getDuration(); 106 Log.v(TAG, "Duration " + duration); 107 mp.release(); 108 Log.v(TAG, "release"); 109 return duration; 110 } 111 getCurrentPosition(String filePath)112 public static boolean getCurrentPosition(String filePath){ 113 Log.v(TAG, "GetCurrentPosition - " + filePath); 114 int currentPosition = 0; 115 long t1=0; 116 long t2 =0; 117 MediaPlayer mp = new MediaPlayer(); 118 try{ 119 mp.setDataSource(filePath); 120 Log.v(TAG, "start playback"); 121 mp.prepare(); 122 mp.start(); 123 t1=SystemClock.uptimeMillis(); 124 Thread.sleep(10000); 125 mp.pause(); 126 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 127 t2=SystemClock.uptimeMillis(); 128 }catch (Exception e){ 129 Log.v(TAG, e.toString()); 130 } 131 currentPosition = mp.getCurrentPosition(); 132 mp.stop(); 133 mp.release(); 134 Log.v(TAG, "mp currentPositon = " + currentPosition + " play duration = " + (t2-t1)); 135 //The currentposition should be within 10% of the sleep time 136 //For the very short mp3, it should return the length instead of 10 seconds 137 if (filePath.equals(MediaNames.SHORTMP3)){ 138 if (currentPosition < 1000 ) 139 return true; 140 } 141 if ((currentPosition < ((t2-t1) *1.2)) && (currentPosition > 0)) 142 return true; 143 else 144 return false; 145 } 146 seekTo(String filePath)147 public static boolean seekTo(String filePath){ 148 Log.v(TAG, "seekTo " + filePath); 149 int currentPosition = 0; 150 MediaPlayer mp = new MediaPlayer(); 151 try{ 152 mp.setDataSource(filePath); 153 mp.prepare(); 154 mp.start(); 155 mp.seekTo(MediaNames.SEEK_TIME); 156 Thread.sleep(MediaNames.WAIT_TIME); 157 currentPosition = mp.getCurrentPosition(); 158 }catch (Exception e){ 159 Log.v(TAG, e.getMessage()); 160 } 161 mp.stop(); 162 mp.release(); 163 Log.v(TAG, "CurrentPosition = " + currentPosition); 164 //The currentposition should be at least greater than the 80% of seek time 165 if ((currentPosition > MediaNames.SEEK_TIME *0.8)) 166 return true; 167 else 168 return false; 169 } 170 setLooping(String filePath)171 public static boolean setLooping(String filePath){ 172 int currentPosition = 0; 173 int duration = 0; 174 long t1 =0; 175 long t2 =0; 176 Log.v (TAG, "SetLooping - " + filePath); 177 MediaPlayer mp = new MediaPlayer(); 178 try{ 179 mp.setDataSource(filePath); 180 mp.prepare(); 181 duration = mp.getDuration(); 182 Log.v(TAG, "setLooping duration " + duration); 183 mp.setLooping(true); 184 mp.start(); 185 Thread.sleep(5000); 186 mp.seekTo(duration - 5000); 187 t1=SystemClock.uptimeMillis(); 188 Thread.sleep(20000); 189 t2=SystemClock.uptimeMillis(); 190 Log.v(TAG, "pause"); 191 //Bug# 1106852 - IllegalStateException will be thrown if pause is called 192 //in here 193 //mp.pause(); 194 currentPosition = mp.getCurrentPosition(); 195 Log.v(TAG, "looping position " + currentPosition + "duration = " + (t2-t1)); 196 }catch (Exception e){ 197 Log.v(TAG, "Exception : " + e.toString()); 198 } 199 mp.stop(); 200 mp.release(); 201 //The current position should be within 20% of the sleep time 202 //and should be greater than zero. 203 if ((currentPosition < ((t2-t1-5000)*1.2)) && currentPosition > 0) 204 return true; 205 else 206 return false; 207 } 208 pause(String filePath)209 public static boolean pause(String filePath) throws Exception { 210 Log.v(TAG, "pause - " + filePath); 211 boolean misPlaying = true; 212 boolean pauseResult = false; 213 long t1=0; 214 long t2=0; 215 MediaPlayer mp = new MediaPlayer(); 216 mp.setDataSource(filePath); 217 mp.prepare(); 218 int duration = mp.getDuration(); 219 mp.start(); 220 t1=SystemClock.uptimeMillis(); 221 Thread.sleep(5000); 222 mp.pause(); 223 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 224 t2=SystemClock.uptimeMillis(); 225 misPlaying = mp.isPlaying(); 226 int curPosition = mp.getCurrentPosition(); 227 Log.v(TAG, filePath + " pause currentPositon " + curPosition); 228 Log.v(TAG, "isPlaying "+ misPlaying + " wait time " + (t2 - t1) ); 229 String cpuinfo = printCpuInfo(); 230 Log.v(TAG, cpuinfo); 231 if ((curPosition>0) && (curPosition < ((t2-t1) * 1.3)) && (misPlaying == false)) 232 pauseResult = true; 233 mp.stop(); 234 mp.release(); 235 return pauseResult; 236 } 237 prepareStopRelease(String filePath)238 public static void prepareStopRelease(String filePath) throws Exception { 239 Log.v(TAG, "prepareStopRelease" + filePath); 240 MediaPlayer mp = new MediaPlayer(); 241 mp.setDataSource(filePath); 242 mp.prepare(); 243 mp.stop(); 244 mp.release(); 245 } 246 preparePauseRelease(String filePath)247 public static void preparePauseRelease(String filePath) throws Exception { 248 Log.v(TAG, "preparePauseRelease" + filePath); 249 MediaPlayer mp = new MediaPlayer(); 250 mp.setDataSource(filePath); 251 mp.prepare(); 252 mp.pause(); 253 mp.release(); 254 } 255 256 static MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener = 257 new MediaPlayer.OnVideoSizeChangedListener() { 258 public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 259 synchronized (videoSizeChanged) { 260 Log.v(TAG, "sizechanged notification received ..."); 261 videoSizeChanged.notify(); 262 } 263 } 264 }; 265 266 //Register the videoSizeChanged listener videoHeight(String filePath)267 public static int videoHeight(String filePath) throws Exception { 268 Log.v(TAG, "videoHeight - " + filePath); 269 int videoHeight = 0; 270 synchronized (lock) { 271 initializeMessageLooper(); 272 try { 273 lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE); 274 } catch(Exception e) { 275 Log.v(TAG, "looper was interrupted."); 276 return 0; 277 } 278 } 279 try { 280 mMediaPlayer.setDataSource(filePath); 281 mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 282 mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener); 283 synchronized (videoSizeChanged) { 284 try { 285 mMediaPlayer.prepare(); 286 mMediaPlayer.start(); 287 videoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE); 288 } catch (Exception e) { 289 Log.v(TAG, "wait was interrupted"); 290 } 291 } 292 videoHeight = mMediaPlayer.getVideoHeight(); 293 terminateMessageLooper(); 294 } catch (Exception e) { 295 Log.e(TAG, e.getMessage()); 296 } 297 298 return videoHeight; 299 } 300 301 //Register the videoSizeChanged listener videoWidth(String filePath)302 public static int videoWidth(String filePath) throws Exception { 303 Log.v(TAG, "videoWidth - " + filePath); 304 int videoWidth = 0; 305 306 synchronized (lock) { 307 initializeMessageLooper(); 308 try { 309 lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE); 310 } catch(Exception e) { 311 Log.v(TAG, "looper was interrupted."); 312 return 0; 313 } 314 } 315 try { 316 mMediaPlayer.setDataSource(filePath); 317 mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 318 mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener); 319 synchronized (videoSizeChanged) { 320 try { 321 mMediaPlayer.prepare(); 322 mMediaPlayer.start(); 323 videoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE); 324 } catch (Exception e) { 325 Log.v(TAG, "wait was interrupted"); 326 } 327 } 328 videoWidth = mMediaPlayer.getVideoWidth(); 329 terminateMessageLooper(); 330 } catch (Exception e) { 331 Log.e(TAG, e.getMessage()); 332 } 333 return videoWidth; 334 } 335 336 //This also test the streaming video which may take a long 337 //time to start the playback. videoSeekTo(String filePath)338 public static boolean videoSeekTo(String filePath) throws Exception { 339 Log.v(TAG, "videoSeekTo - " + filePath); 340 int currentPosition = 0; 341 int duration = 0; 342 boolean videoResult = false; 343 MediaPlayer mp = new MediaPlayer(); 344 mp.setDataSource(filePath); 345 mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 346 mp.prepare(); 347 mp.start(); 348 if (filePath.equals(MediaNames.VIDEO_SHORT_3GP)){ 349 mp.pause(); 350 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 351 mp.seekTo(0); 352 mp.start(); 353 Thread.sleep(1000); 354 currentPosition = mp.getCurrentPosition(); 355 Log.v(TAG,"short position " + currentPosition); 356 if (currentPosition > 100 ) 357 return true; 358 else 359 return false; 360 } 361 Thread.sleep(5000); 362 duration = mp.getDuration(); 363 Log.v(TAG, "video duration " + duration); 364 mp.pause(); 365 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 366 mp.seekTo(duration - 20000 ); 367 mp.start(); 368 Thread.sleep(1000); 369 mp.pause(); 370 Thread.sleep(MediaNames.PAUSE_WAIT_TIME); 371 mp.seekTo(duration/2); 372 mp.start(); 373 Thread.sleep(10000); 374 currentPosition = mp.getCurrentPosition(); 375 Log.v(TAG, "video currentPosition " + currentPosition); 376 mp.release(); 377 if (currentPosition > (duration /2 )*0.9) 378 return true; 379 else 380 return false; 381 382 } 383 seekToEnd(String filePath)384 public static boolean seekToEnd(String filePath){ 385 Log.v(TAG, "seekToEnd - " + filePath); 386 int duration = 0; 387 int currentPosition = 0; 388 boolean isPlaying = false; 389 MediaPlayer mp = new MediaPlayer(); 390 try{ 391 mp.setDataSource(filePath); 392 Log.v(TAG, "start playback"); 393 mp.prepare(); 394 duration = mp.getDuration(); 395 mp.seekTo(duration - 3000); 396 mp.start(); 397 Thread.sleep(6000); 398 }catch (Exception e){} 399 isPlaying = mp.isPlaying(); 400 currentPosition = mp.getCurrentPosition(); 401 Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying); 402 mp.stop(); 403 mp.release(); 404 Log.v(TAG, "duration = " + duration); 405 if (currentPosition < 0.9 * duration || isPlaying) 406 return false; 407 else 408 return true; 409 } 410 shortMediaStop(String filePath)411 public static boolean shortMediaStop(String filePath){ 412 Log.v(TAG, "shortMediaStop - " + filePath); 413 //This test is only for the short media file 414 int duration = 0; 415 int currentPosition = 0; 416 boolean isPlaying = false; 417 MediaPlayer mp = new MediaPlayer(); 418 try{ 419 mp.setDataSource(filePath); 420 Log.v(TAG, "start playback"); 421 mp.prepare(); 422 duration = mp.getDuration(); 423 mp.start(); 424 Thread.sleep(10000); 425 }catch (Exception e){} 426 isPlaying = mp.isPlaying(); 427 currentPosition = mp.getCurrentPosition(); 428 Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying); 429 mp.stop(); 430 mp.release(); 431 Log.v(TAG, "duration = " + duration); 432 if (currentPosition > duration || isPlaying) 433 return false; 434 else 435 return true; 436 } 437 playToEnd(String filePath)438 public static boolean playToEnd(String filePath){ 439 Log.v(TAG, "shortMediaStop - " + filePath); 440 //This test is only for the short media file 441 int duration = 200000; 442 int updateDuration = 0; 443 int currentPosition = 0; 444 boolean isPlaying = false; 445 MediaPlayer mp = new MediaPlayer(); 446 try{ 447 Thread.sleep(5000); 448 mp.setDataSource(filePath); 449 Log.v(TAG, "start playback"); 450 mp.prepare(); 451 //duration = mp.getDuration(); 452 mp.start(); 453 Thread.sleep(50000); 454 }catch (Exception e){} 455 isPlaying = mp.isPlaying(); 456 currentPosition = mp.getCurrentPosition(); 457 //updateDuration = mp.getDuration(); 458 Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying); 459 mp.stop(); 460 mp.release(); 461 //Log.v(TAG, "duration = " + duration); 462 //Log.v(TAG, "Update duration = " + updateDuration); 463 if (currentPosition > duration || isPlaying) 464 return false; 465 else 466 return true; 467 } 468 seektoBeforeStart(String filePath)469 public static boolean seektoBeforeStart(String filePath){ 470 Log.v(TAG, "seektoBeforeStart - " + filePath); 471 //This test is only for the short media file 472 int duration = 0; 473 int currentPosition = 0; 474 475 MediaPlayer mp = new MediaPlayer(); 476 try{ 477 mp.setDataSource(filePath); 478 mp.prepare(); 479 duration = mp.getDuration(); 480 mp.seekTo(duration - 10000); 481 mp.start(); 482 currentPosition=mp.getCurrentPosition(); 483 mp.stop(); 484 mp.release(); 485 }catch (Exception e){} 486 if (currentPosition < duration/2) 487 return false; 488 else 489 return true; 490 } 491 mediaRecorderRecord(String filePath)492 public static boolean mediaRecorderRecord(String filePath){ 493 Log.v(TAG, "SoundRecording - " + filePath); 494 //This test is only for the short media file 495 int duration = 0; 496 try{ 497 MediaRecorder mRecorder = new MediaRecorder(); 498 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 499 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 500 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 501 mRecorder.setOutputFile(filePath); 502 mRecorder.prepare(); 503 mRecorder.start(); 504 Thread.sleep(500); 505 mRecorder.stop(); 506 Log.v(TAG, "sound recorded"); 507 mRecorder.release(); 508 }catch (Exception e){ 509 Log.v(TAG, e.toString()); 510 } 511 512 //Verify the recorded file 513 MediaPlayer mp = new MediaPlayer(); 514 try{ 515 mp.setDataSource(filePath); 516 mp.prepare(); 517 duration = mp.getDuration(); 518 Log.v(TAG,"Duration " + duration); 519 mp.release(); 520 }catch (Exception e){} 521 //Check the record media file length is greate than zero 522 if (duration > 0) 523 return true; 524 else 525 return false; 526 527 } 528 529 //Test for mediaMeta Data Thumbnail getThumbnail(String filePath, String goldenPath)530 public static boolean getThumbnail(String filePath, String goldenPath){ 531 Log.v(TAG, "getThumbnail - " + filePath); 532 533 int goldenHeight = 0; 534 int goldenWidth = 0; 535 int outputWidth = 0; 536 int outputHeight = 0; 537 538 //This test is only for the short media file 539 try{ 540 BitmapFactory mBitmapFactory = new BitmapFactory(); 541 542 MediaMetadataRetriever mMediaMetadataRetriever = new MediaMetadataRetriever(); 543 try { 544 mMediaMetadataRetriever.setDataSource(filePath); 545 } catch(Exception e) { 546 e.printStackTrace(); 547 return false; 548 } 549 Bitmap outThumbnail = mMediaMetadataRetriever.getFrameAtTime(-1); 550 551 //Verify the thumbnail 552 Bitmap goldenBitmap = mBitmapFactory.decodeFile(goldenPath); 553 outputWidth = outThumbnail.getWidth(); 554 outputHeight = outThumbnail.getHeight(); 555 goldenHeight = goldenBitmap.getHeight(); 556 goldenWidth = goldenBitmap.getWidth(); 557 558 //check the image dimension 559 if ((outputWidth != goldenWidth) || (outputHeight != goldenHeight)) 560 return false; 561 562 // Check half line of pixel 563 int x = goldenHeight / 2; 564 for (int j = 1; j < goldenWidth / 2; j++) { 565 if (goldenBitmap.getPixel(x, j) != outThumbnail.getPixel(x, j)) { 566 Log.v(TAG, "pixel = " + goldenBitmap.getPixel(x, j)); 567 return false; 568 } 569 } 570 }catch (Exception e){ 571 Log.v(TAG, e.toString()); 572 return false; 573 } 574 return true; 575 } 576 577 //Load midi file from resources resourcesPlayback(AssetFileDescriptor afd, int expectedDuration)578 public static boolean resourcesPlayback(AssetFileDescriptor afd, int expectedDuration){ 579 int duration = 0; 580 try{ 581 MediaPlayer mp = new MediaPlayer(); 582 mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength()); 583 mp.prepare(); 584 mp.start(); 585 duration = mp.getDuration(); 586 Thread.sleep(5000); 587 mp.release(); 588 }catch (Exception e){ 589 Log.v(TAG,e.getMessage()); 590 } 591 if (duration > expectedDuration) 592 return true; 593 else 594 return false; 595 } 596 prepareAsyncReset(String filePath)597 public static boolean prepareAsyncReset(String filePath){ 598 //preparesAsync 599 try{ 600 MediaPlayer mp = new MediaPlayer(); 601 mp.setDataSource(filePath); 602 mp.prepareAsync(); 603 mp.reset(); 604 mp.release(); 605 }catch (Exception e){ 606 Log.v(TAG,e.getMessage()); 607 return false; 608 } 609 return true; 610 } 611 612 isLooping(String filePath)613 public static boolean isLooping(String filePath) { 614 MediaPlayer mp = null; 615 616 try { 617 mp = new MediaPlayer(); 618 if (mp.isLooping()) { 619 Log.v(TAG, "MediaPlayer.isLooping() returned true after ctor"); 620 return false; 621 } 622 mp.setDataSource(filePath); 623 mp.prepare(); 624 625 mp.setLooping(true); 626 if (!mp.isLooping()) { 627 Log.v(TAG, "MediaPlayer.isLooping() returned false after setLooping(true)"); 628 return false; 629 } 630 631 mp.setLooping(false); 632 if (mp.isLooping()) { 633 Log.v(TAG, "MediaPlayer.isLooping() returned true after setLooping(false)"); 634 return false; 635 } 636 }catch (Exception e){ 637 Log.v(TAG, "Exception : " + e.toString()); 638 return false; 639 } finally { 640 if (mp != null) 641 mp.release(); 642 } 643 644 return true; 645 } 646 isLoopingAfterReset(String filePath)647 public static boolean isLoopingAfterReset(String filePath) { 648 MediaPlayer mp = null; 649 try { 650 mp = new MediaPlayer(); 651 mp.setDataSource(filePath); 652 mp.prepare(); 653 654 mp.setLooping(true); 655 mp.reset(); 656 if (mp.isLooping()) { 657 Log.v(TAG, "MediaPlayer.isLooping() returned true after reset()"); 658 return false; 659 } 660 }catch (Exception e){ 661 Log.v(TAG, "Exception : " + e.toString()); 662 return false; 663 } finally { 664 if (mp != null) 665 mp.release(); 666 } 667 668 return true; 669 } 670 671 /* 672 * Initializes the message looper so that the mediaPlayer object can 673 * receive the callback messages. 674 */ initializeMessageLooper()675 private static void initializeMessageLooper() { 676 Log.v(TAG, "start looper"); 677 new Thread() { 678 @Override 679 public void run() { 680 // Set up a looper to be used by camera. 681 Looper.prepare(); 682 Log.v(TAG, "start loopRun"); 683 // Save the looper so that we can terminate this thread 684 // after we are done with it. 685 mLooper = Looper.myLooper(); 686 mMediaPlayer = new MediaPlayer(); 687 synchronized (lock) { 688 mInitialized = true; 689 lock.notify(); 690 } 691 Looper.loop(); // Blocks forever until Looper.quit() is called. 692 Log.v(TAG, "initializeMessageLooper: quit."); 693 } 694 }.start(); 695 } 696 697 /* 698 * Terminates the message looper thread. 699 */ terminateMessageLooper()700 private static void terminateMessageLooper() { 701 mLooper.quit(); 702 mMediaPlayer.release(); 703 } 704 705 static MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() { 706 public void onPrepared(MediaPlayer mp) { 707 synchronized (prepareDone) { 708 if(mPrepareReset){ 709 Log.v(TAG, "call Reset"); 710 mMediaPlayer.reset(); 711 } 712 Log.v(TAG, "notify the prepare callback"); 713 prepareDone.notify(); 714 onPrepareSuccess = true; 715 } 716 } 717 }; 718 prepareAsyncCallback(String filePath, boolean reset)719 public static boolean prepareAsyncCallback(String filePath, boolean reset) throws Exception { 720 //Added the PrepareReset flag which allow us to switch to different 721 //test case. 722 if (reset){ 723 mPrepareReset = true; 724 } 725 726 synchronized (lock) { 727 initializeMessageLooper(); 728 try { 729 lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE); 730 } catch(Exception e) { 731 Log.v(TAG, "looper was interrupted."); 732 return false; 733 } 734 } 735 try{ 736 mMediaPlayer.setOnPreparedListener(mPreparedListener); 737 mMediaPlayer.setDataSource(filePath); 738 mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 739 mMediaPlayer.prepareAsync(); 740 synchronized (prepareDone) { 741 try { 742 prepareDone.wait(WAIT_FOR_COMMAND_TO_COMPLETE); 743 } catch (Exception e) { 744 Log.v(TAG, "wait was interrupted."); 745 } 746 } 747 terminateMessageLooper(); 748 }catch (Exception e){ 749 Log.v(TAG,e.getMessage()); 750 } 751 return onPrepareSuccess; 752 } 753 754 static MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() { 755 public void onCompletion(MediaPlayer mp) { 756 synchronized (onCompletion) { 757 Log.v(TAG, "notify the completion callback"); 758 onCompletion.notify(); 759 onCompleteSuccess = true; 760 } 761 } 762 }; 763 764 static MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() { 765 public boolean onError(MediaPlayer mp, int framework_err, int impl_err) { 766 mPlaybackError = true; 767 mp.reset(); 768 return true; 769 } 770 }; 771 772 static MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() { 773 public boolean onInfo(MediaPlayer mp, int what, int extra) { 774 switch (what){ 775 case MediaPlayer.MEDIA_INFO_UNKNOWN: 776 mMediaInfoUnknownCount++; 777 break; 778 case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING: 779 mMediaInfoVideoTrackLaggingCount++; 780 break; 781 case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING: 782 mMediaInfoBadInterleavingCount++; 783 break; 784 case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE: 785 mMediaInfoNotSeekableCount++; 786 break; 787 case MediaPlayer.MEDIA_INFO_METADATA_UPDATE: 788 mMediaInfoMetdataUpdateCount++; 789 break; 790 } 791 return true; 792 } 793 }; 794 playMediaSamples(String filePath)795 public static boolean playMediaSamples(String filePath) throws Exception { 796 return playMediaSamples(filePath, 2000, false /* streamingTest */); 797 } 798 799 // For each media file, just play to the end playMediaSamples(String filePath, int buffertime, boolean streamingTest)800 public static boolean playMediaSamples(String filePath, int buffertime, boolean streamingTest) 801 throws Exception { 802 int duration = 0; 803 int curPosition = 0; 804 int nextPosition = 0; 805 int waittime = 0; 806 onCompleteSuccess = false; 807 mMediaInfoUnknownCount = 0; 808 mMediaInfoVideoTrackLaggingCount = 0; 809 mMediaInfoBadInterleavingCount = 0; 810 mMediaInfoNotSeekableCount = 0; 811 mMediaInfoMetdataUpdateCount = 0; 812 mPlaybackError = false; 813 mFailedToCompleteWithNoError = true; 814 String testResult; 815 816 boolean hasSupportedVideo = false; 817 818 if (!streamingTest) { 819 if (mSupportedTypes.isEmpty()) { 820 final MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS); 821 for (MediaCodecInfo info : list.getCodecInfos()) { 822 for (String type : info.getSupportedTypes()) { 823 mSupportedTypes.add(type); 824 } 825 } 826 } 827 final MediaExtractor extractor = new MediaExtractor(); 828 829 try { 830 extractor.setDataSource(filePath); 831 832 for (int index = 0; index < extractor.getTrackCount(); ++index) { 833 MediaFormat format = extractor.getTrackFormat(index); 834 String type = format.getString(MediaFormat.KEY_MIME); 835 if (!type.startsWith("video/")) { 836 continue; 837 } 838 839 if (mSupportedTypes.contains(type)) { 840 hasSupportedVideo = true; 841 break; 842 } 843 } 844 } finally { 845 extractor.release(); 846 } 847 } else { // streamingTest 848 hasSupportedVideo = true; 849 } 850 851 initializeMessageLooper(); 852 synchronized (lock) { 853 try { 854 lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE); 855 } catch(Exception e) { 856 Log.v(TAG, "looper was interrupted."); 857 return false; 858 } 859 } 860 try { 861 mMediaPlayer.setOnCompletionListener(mCompletionListener); 862 mMediaPlayer.setOnErrorListener(mOnErrorListener); 863 mMediaPlayer.setOnInfoListener(mInfoListener); 864 Log.v(TAG, "playMediaSamples: sample file name " + filePath); 865 mMediaPlayer.setDataSource(filePath); 866 if (hasSupportedVideo) { 867 mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 868 } else { 869 Log.i(TAG, "Set no display due to no (supported) video track."); 870 mMediaPlayer.setDisplay(null); 871 } 872 mMediaPlayer.prepare(); 873 duration = mMediaPlayer.getDuration(); 874 // start to play 875 mMediaPlayer.start(); 876 if (duration < 0) { 877 Log.w(TAG, filePath + " has unknown duration, waiting until playback completes"); 878 while (mMediaPlayer.isPlaying()) { 879 SystemClock.sleep(1000); 880 } 881 } else { 882 waittime = duration - mMediaPlayer.getCurrentPosition(); 883 synchronized(onCompletion){ 884 try { 885 onCompletion.wait(waittime + buffertime); 886 } catch (Exception e) { 887 Log.v(TAG, "playMediaSamples are interrupted"); 888 return false; 889 } 890 } 891 } 892 terminateMessageLooper(); 893 } catch (Exception e) { 894 Log.v(TAG, "playMediaSamples:" + e.getMessage()); 895 } 896 // Check if playback state is unknown (neither completed nor erroneous) unless 897 // it's not interrupted in the middle. If true, that is an exceptional case to investigate. 898 mFailedToCompleteWithNoError = !(onCompleteSuccess || mPlaybackError); 899 return onCompleteSuccess; 900 } 901 } 902