1 /* 2 * Copyright (C) 2012 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 /* Original code copied from NDK Native-media sample code */ 18 package android.mediastress.cts; 19 20 import android.app.Activity; 21 import android.content.res.Configuration; 22 import android.graphics.SurfaceTexture; 23 import android.os.Bundle; 24 import android.util.Log; 25 import android.view.Surface; 26 import android.view.WindowManager; 27 28 import java.io.File; 29 import java.util.concurrent.BlockingQueue; 30 import java.util.concurrent.LinkedBlockingQueue; 31 import java.util.concurrent.TimeUnit; 32 33 import junit.framework.Assert; 34 35 public class NativeMediaActivity extends Activity implements OnSurfaceChangedListener { 36 public static final String EXTRA_VIDEO_HEIGHT = "videoHeight"; 37 // should be long enough. time-out can be treated as error 38 public static final long NATIVE_MEDIA_LIFECYCLE_TIMEOUT_MS = 10000; 39 static final String TAG = "NativeMedia"; 40 static final String[] MEDIA = { 41 "bbb_short/480x360/mp4_libx264_libfaac/" + 42 "bbb_short.ffmpeg.480x360.mp4.libx264_1000kbps_30fps.libfaac_stereo_192kbps_44100Hz.ts", 43 "bbb_short/720x480/mp4_libx264_libfaac/" + 44 "bbb_short.ffmpeg.720x480.mp4.libx264_1000kbps_30fps.libfaac_stereo_192kbps_44100Hz.ts", 45 "bbb_short/1280x720/mp4_libx264_libfaac/" + 46 "bbb_short.ffmpeg.1280x720.mp4.libx264_1000kbps_30fps.libfaac_stereo_192kbps_44100Hz.ts", 47 "bbb_short/1920x1080/mp4_libx264_libfaac/" + 48 "bbb_short.ffmpeg.1920x1080.mp4.libx264_5000kbps_30fps.libfaac_stereo_192kbps_48000Hz.ts" 49 }; 50 51 private SurfaceTextureGLSurfaceView mGLView; 52 private volatile boolean mNativeCreated = false; 53 private int mVideoHeight = 360; 54 // native media status queued whenever there is a change in life. 55 private final BlockingQueue<Boolean> mNativeWaitQ = new LinkedBlockingQueue<Boolean>(); 56 57 @Override onCreate(Bundle icicle)58 public void onCreate(Bundle icicle) { 59 super.onCreate(icicle); 60 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | 61 WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); 62 mVideoHeight = getIntent().getIntExtra(EXTRA_VIDEO_HEIGHT, mVideoHeight); 63 mGLView = new SurfaceTextureGLSurfaceView(this, this); 64 setContentView(mGLView); 65 } 66 67 @Override onConfigurationChanged(Configuration newConfig)68 public void onConfigurationChanged(Configuration newConfig) { 69 Log.w(TAG, "configuration changed " + newConfig.orientation); 70 super.onConfigurationChanged(newConfig); 71 } 72 73 /** 74 * should be called by GLThread after GlSurface is created. 75 */ 76 @Override onSurfaceCreated()77 public void onSurfaceCreated() { 78 runOnUiThread(new Runnable() { 79 @Override 80 public void run() { 81 Log.i(TAG, "onSurfaceCreated create engine"); 82 // initialize native media system 83 Assert.assertTrue(createEngine()); 84 Assert.assertTrue(setSurfaceForNative()); 85 String fileName = getMediaString(); 86 File f = new File(fileName); 87 Log.i(TAG, "start playing " + fileName + ", exists: " + f.exists()); 88 Assert.assertTrue("file '" + fileName + "' does not exist", f.exists()); 89 Assert.assertTrue(createMediaPlayer("file://" + fileName)); 90 mNativeCreated = true; 91 mNativeWaitQ.add(mNativeCreated); 92 } 93 }); 94 } 95 96 /** 97 * should be called inside main thread 98 */ 99 @Override onSurfaceDestroyed()100 public void onSurfaceDestroyed() { 101 shutdownIfActive(); 102 } 103 104 /** 105 * check if native media is alive. If it does not become alive 106 * for more than certain time, assertion fail will happen. 107 * @return the status of native media, true if it is alive, null if timed-out 108 * @throws InterruptedException 109 */ waitForNativeMediaLifeCycle()110 public Boolean waitForNativeMediaLifeCycle() throws InterruptedException { 111 return mNativeWaitQ.poll(NATIVE_MEDIA_LIFECYCLE_TIMEOUT_MS, TimeUnit.MILLISECONDS); 112 } 113 114 @Override onPause()115 protected void onPause() { 116 //GLSurfaceView destroys surface on pause. so shutdown should be done. 117 shutdownIfActive(); 118 mGLView.onPause(); 119 super.onPause(); 120 } 121 122 @Override onResume()123 protected void onResume() { 124 super.onResume(); 125 mGLView.onResume(); 126 if (mNativeCreated) { 127 Assert.assertTrue(playOrPauseMediaPlayer(true)); 128 } 129 } 130 131 @Override onDestroy()132 protected void onDestroy() { 133 if (mNativeCreated) { 134 shutdown(); 135 } 136 super.onDestroy(); 137 } 138 shutdownIfActive()139 private void shutdownIfActive() { 140 if (mNativeCreated) { 141 Log.i(TAG, "shutdownIfActive shutdown"); 142 // surface no longer available, so just shutdown 143 shutdown(); 144 mNativeCreated = false; 145 mNativeWaitQ.add(mNativeCreated); 146 } 147 } 148 setSurfaceForNative()149 private boolean setSurfaceForNative() { 150 SurfaceTexture st = mGLView.getSurfaceTexture(); 151 Assert.assertNotNull(st); 152 Surface s = new Surface(st); 153 boolean res = setSurface(s); 154 s.release(); 155 return res; 156 } 157 getMediaString()158 private String getMediaString() { 159 int mediaIndex = 0; // default: 480x360 160 switch(mVideoHeight) { 161 case 1080: 162 mediaIndex = 3; 163 break; 164 case 720: 165 mediaIndex = 2; 166 break; 167 case 480: 168 mediaIndex = 1; 169 break; 170 } 171 return WorkDir.getMediaDirString() + MEDIA[mediaIndex]; 172 } 173 174 /** 175 * creates OpenMaxAl Engine 176 */ createEngine()177 public static native boolean createEngine(); 178 /** 179 * set surface to render. should be called before creating Media player 180 * @param surface 181 */ setSurface(Surface surface)182 public static native boolean setSurface(Surface surface); 183 createMediaPlayer(String fileUri)184 public static native boolean createMediaPlayer(String fileUri); playOrPauseMediaPlayer(boolean play)185 public static native boolean playOrPauseMediaPlayer(boolean play); shutdown()186 public static native void shutdown(); 187 188 /** Load jni on initialization */ 189 static { 190 System.loadLibrary("ctsmediastress_jni"); 191 } 192 193 } 194