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