1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/* 2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright (C) 2011 The Android Open Source Project 3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License"); 5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License. 6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at 7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * http://www.apache.org/licenses/LICENSE-2.0 9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software 11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS, 12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and 14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License. 15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspackage androidx.media.filterfw; 18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.annotation.TargetApi; 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.app.Activity; 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.app.ActivityManager; 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.content.Context; 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.content.pm.ConfigurationInfo; 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Build; 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Handler; 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Looper; 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.renderscript.RenderScript; 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.util.Log; 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.SurfaceHolder; 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.SurfaceView; 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.ViewGroup; 32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.HashSet; 34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.Set; 35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/** 37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * The MffContext holds the state and resources of a Mobile Filter Framework processing instance. 38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Though it is possible to create multiple MffContext instances, typical applications will rely on 39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * a single MffContext to perform all processing within the Mobile Filter Framework. 40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * The MffContext class declares two methods {@link #onPause()} and {@link #onResume()}, that are 42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * typically called when the application activity is paused and resumed. This will take care of 43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * halting any processing in the context, and releasing resources while the activity is paused. 44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic class MffContext { 46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Class to hold configuration information for MffContexts. 49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static class Config { 51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Set to true, if this context will make use of the camera. 53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * If your application does not require the camera, the context does not guarantee that 54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * a camera is available for streaming. That is, you may only use a CameraStreamer if 55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * the context's {@link #isCameraStreamingSupported()} returns true. 56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean requireCamera = true; 58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Set to true, if this context requires OpenGL. 61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * If your application does not require OpenGL, the context does not guarantee that OpenGL 62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * is available. That is, you may only use OpenGL (within filters running in this context) 63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * if the context's {@link #isOpenGLSupported()} method returns true. 64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean requireOpenGL = true; 66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * On older Android versions the Camera may need a SurfaceView to render into in order to 69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * function. You may specify a dummy SurfaceView here if you do not want the context to 70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * create its own view. Note, that your view may or may not be used. You cannot rely on 71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * your dummy view to be used by the Camera. If you pass null, no dummy view will be used. 72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * In this case your application may not run correctly on older devices if you use the 73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * camera. This flag has no effect if you do not require the camera. 74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public SurfaceView dummySurface = null; 76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** Force MFF to not use OpenGL in its processing. */ 78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean forceNoGL = false; 79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks static private class State { 82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static final int STATE_RUNNING = 1; 83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static final int STATE_PAUSED = 2; 84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static final int STATE_DESTROYED = 3; 85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public int current = STATE_RUNNING; 87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** The application context. */ 90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Context mApplicationContext = null; 91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** The set of filter graphs within this context */ 93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Set<FilterGraph> mGraphs = new HashSet<FilterGraph>(); 94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** The set of graph runners within this context */ 96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Set<GraphRunner> mRunners = new HashSet<GraphRunner>(); 97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** True, if the context preserves frames when paused. */ 99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mPreserveFramesOnPause = false; 100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** The shared CameraStreamer that streams camera frames to CameraSource filters. */ 102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private CameraStreamer mCameraStreamer = null; 103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** The current context state. */ 105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private State mState = new State(); 106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** A dummy SurfaceView that is required for Camera operation on older devices. */ 108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private SurfaceView mDummySurfaceView = null; 109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** Handler to execute code in the context's thread, such as issuing callbacks. */ 111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Handler mHandler = null; 112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** Flag whether OpenGL ES 2 is supported in this context. */ 114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mGLSupport; 115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** Flag whether camera streaming is supported in this context. */ 117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mCameraStreamingSupport; 118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** RenderScript base master class. */ 120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private RenderScript mRenderScript; 121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Creates a new MffContext with the default configuration. 124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * An MffContext must be attached to a Context object of an application. You may create 126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * multiple MffContexts, however data between them cannot be shared. The context must be 127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * created in a thread with a Looper (such as the main/UI thread). 128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * On older versions of Android, the MffContext may create a visible dummy view for the 130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * camera to render into. This is a 1x1 SurfaceView that is placed into the top-left corner. 131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param context The application context to attach the MffContext to. 133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public MffContext(Context context) { 135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks init(context, new Config()); 136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Creates a new MffContext with the specified configuration. 140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * An MffContext must be attached to a Context object of an application. You may create 142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * multiple MffContexts, however data between them cannot be shared. The context must be 143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * created in a thread with a Looper (such as the main/UI thread). 144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * On older versions of Android, the MffContext may create a visible dummy view for the 146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * camera to render into. This is a 1x1 SurfaceView that is placed into the top-left corner. 147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may alternatively specify your own SurfaceView in the configuration. 148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param context The application context to attach the MffContext to. 150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param config The configuration to use. 151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @throws RuntimeException If no context for the requested configuration could be created. 153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public MffContext(Context context, Config config) { 155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks init(context, config); 156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Put all processing in the context on hold. 160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is typically called from your application's <code>onPause()</code> method, and will 161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * stop all running graphs (closing their filters). If the context does not preserve frames on 162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * pause (see {@link #setPreserveFramesOnPause(boolean)}) all frames attached to this context 163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * are released. 164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void onPause() { 166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mState) { 167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current == State.STATE_RUNNING) { 168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mCameraStreamer != null) { 169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCameraStreamer.halt(); 170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stopRunners(true); 172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mState.current = State.STATE_PAUSED; 173227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 174227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 175227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 176227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 177227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 178227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Resumes the processing in this context. 179227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is typically called from the application's <code>onResume()</code> method, and will 180227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * resume processing any of the previously stopped filter graphs. 181227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 182227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void onResume() { 183227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mState) { 184227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current == State.STATE_PAUSED) { 185227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks resumeRunners(); 186227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks resumeCamera(); 187227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mState.current = State.STATE_RUNNING; 188227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 189227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 190227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 191227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 192227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 193227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Release all resources associated with this context. 194227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This will also stop any running graphs. 195227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 196227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void release() { 197227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mState) { 198227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current != State.STATE_DESTROYED) { 199227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mCameraStreamer != null) { 200227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCameraStreamer.stop(); 201227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCameraStreamer.tearDown(); 202227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 203227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (Build.VERSION.SDK_INT >= 11) { 204227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks maybeDestroyRenderScript(); 205227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 206227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stopRunners(false); 207227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks waitUntilStopped(); 208227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks tearDown(); 209227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mState.current = State.STATE_DESTROYED; 210227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 211227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 212227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 213227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 214227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 215227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Set whether frames are preserved when the context is paused. 216227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * When passing false, all Frames associated with this context are released. The default 217227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * value is true. 218227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 219227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param preserve true, to preserve frames when the context is paused. 220227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 221227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #getPreserveFramesOnPause() 222227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 223227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void setPreserveFramesOnPause(boolean preserve) { 224227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mPreserveFramesOnPause = preserve; 225227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 226227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 227227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 228227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns whether frames are preserved when the context is paused. 229227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 230227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if frames are preserved when the context is paused. 231227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 232227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #setPreserveFramesOnPause(boolean) 233227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 234227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean getPreserveFramesOnPause() { 235227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mPreserveFramesOnPause; 236227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 237227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 238227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 239227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the application context that the MffContext is attached to. 240227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 241227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return The application context for this context. 242227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 243227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public Context getApplicationContext() { 244227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mApplicationContext; 245227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 246227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 247227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 248227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the context's shared CameraStreamer. 249227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Use the CameraStreamer to control the Camera. Frames from the Camera are typically streamed 250227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * to CameraSource filters. 251227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 252227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return The context's CameraStreamer instance. 253227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 254227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public CameraStreamer getCameraStreamer() { 255227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mCameraStreamer == null) { 256227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCameraStreamer = new CameraStreamer(this); 257227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 258227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mCameraStreamer; 259227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 260227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 261227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 262227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Set the default EGL config chooser. 263227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 264227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * When an EGL context is required by the MFF, the channel sizes specified here are used. The 265227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * default sizes are 8 bits per R,G,B,A channel and 0 bits for depth and stencil channels. 266227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 267227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param redSize The size of the red channel in bits. 268227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param greenSize The size of the green channel in bits. 269227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param blueSize The size of the blue channel in bits. 270227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param alphaSize The size of the alpha channel in bits. 271227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param depthSize The size of the depth channel in bits. 272227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param stencilSize The size of the stencil channel in bits. 273227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 274227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static void setEGLConfigChooser(int redSize, 275227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int greenSize, 276227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int blueSize, 277227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int alphaSize, 278227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int depthSize, 279227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int stencilSize) { 280227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks RenderTarget.setEGLConfigChooser(redSize, 281227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks greenSize, 282227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks blueSize, 283227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks alphaSize, 284227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks depthSize, 285227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks stencilSize); 286227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 287227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 288227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 289227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns true, if this context supports using OpenGL. 290227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if this context supports using OpenGL. 291227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 292227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final boolean isOpenGLSupported() { 293227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mGLSupport; 294227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 295227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 296227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 297227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns true, if this context supports camera streaming. 298227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if this context supports camera streaming. 299227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 300227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final boolean isCameraStreamingSupported() { 301227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mCameraStreamingSupport; 302227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 303227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 304227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @TargetApi(11) 305227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final RenderScript getRenderScript() { 306227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mRenderScript == null) { 307227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mRenderScript = RenderScript.create(mApplicationContext); 308227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 309227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mRenderScript; 310227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 311227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 312227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void assertOpenGLSupported() { 313227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!isOpenGLSupported()) { 314227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Attempting to use OpenGL ES 2 in a context that does not " 315227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "support it!"); 316227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 317227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 318227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 319227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void addGraph(FilterGraph graph) { 320227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mGraphs) { 321227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mGraphs.add(graph); 322227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 323227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 324227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 325227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void addRunner(GraphRunner runner) { 326227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mRunners) { 327227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mRunners.add(runner); 328227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 329227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 330227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 331227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks SurfaceView getDummySurfaceView() { 332227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mDummySurfaceView; 333227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 334227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 335227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void postRunnable(Runnable runnable) { 336227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mHandler.post(runnable); 337227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 338227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 339227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void init(Context context, Config config) { 340227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks determineGLSupport(context, config); 341227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks determineCameraSupport(config); 342227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks createHandler(); 343227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mApplicationContext = context.getApplicationContext(); 344227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks fetchDummySurfaceView(context, config); 345227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 346227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 347227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void fetchDummySurfaceView(Context context, Config config) { 348227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (config.requireCamera && CameraStreamer.requireDummySurfaceView()) { 349227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mDummySurfaceView = config.dummySurface != null 350227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ? config.dummySurface 351227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks : createDummySurfaceView(context); 352227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 353227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 354227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 355227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void determineGLSupport(Context context, Config config) { 356227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (config.forceNoGL) { 357227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mGLSupport = false; 358227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 359227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mGLSupport = getPlatformSupportsGLES2(context); 360227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (config.requireOpenGL && !mGLSupport) { 361227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Cannot create context that requires GL support on " 362227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "this platform!"); 363227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 364227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 365227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 366227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 367227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void determineCameraSupport(Config config) { 368227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCameraStreamingSupport = (CameraStreamer.getNumberOfCameras() > 0); 369227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (config.requireCamera && !mCameraStreamingSupport) { 370227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Cannot create context that requires a camera on " 371227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "this platform!"); 372227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 373227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 374227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 375227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static boolean getPlatformSupportsGLES2(Context context) { 376227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 377227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ConfigurationInfo configurationInfo = am.getDeviceConfigurationInfo(); 378227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return configurationInfo.reqGlEsVersion >= 0x20000; 379227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 380227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 381227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void createHandler() { 382227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (Looper.myLooper() == null) { 383227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("MffContext must be created in a thread with a Looper!"); 384227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 385227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mHandler = new Handler(); 386227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 387227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 388227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void stopRunners(boolean haltOnly) { 389227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mRunners) { 390227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Halt all runners (does nothing if not running) 391227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (GraphRunner runner : mRunners) { 392227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (haltOnly) { 393227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks runner.halt(); 394227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 395227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks runner.stop(); 396227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 397227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 398227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Flush all graphs if requested (this is queued up after the call to halt) 399227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!mPreserveFramesOnPause) { 400227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (GraphRunner runner : mRunners) { 401227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks runner.flushFrames(); 402227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 403227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 404227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 405227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 406227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 407227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void resumeRunners() { 408227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mRunners) { 409227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (GraphRunner runner : mRunners) { 410227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks runner.restart(); 411227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 412227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 413227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 414227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 415227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void resumeCamera() { 416227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Restart only affects previously halted cameras that were running. 417227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mCameraStreamer != null) { 418227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCameraStreamer.restart(); 419227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 420227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 421227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 422227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void waitUntilStopped() { 423227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (GraphRunner runner : mRunners) { 424227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks runner.waitUntilStop(); 425227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 426227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 427227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 428227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void tearDown() { 429227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Tear down graphs 430227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (FilterGraph graph : mGraphs) { 431227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks graph.tearDown(); 432227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 433227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 434227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Tear down runners 435227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (GraphRunner runner : mRunners) { 436227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks runner.tearDown(); 437227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 438227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 439227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 440227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @SuppressWarnings("deprecation") 441227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private SurfaceView createDummySurfaceView(Context context) { 442227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // This is only called on Gingerbread devices, so deprecation warning is unnecessary. 443227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks SurfaceView dummySurfaceView = new SurfaceView(context); 444227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks dummySurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 445227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // If we have an activity for this context we'll add the SurfaceView to it (as a 1x1 view 446227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // in the top-left corner). If not, we warn the user that they may need to add one manually. 447227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Activity activity = findActivityForContext(context); 448227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (activity != null) { 449227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(1, 1); 450227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks activity.addContentView(dummySurfaceView, params); 451227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 452227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Log.w("MffContext", "Could not find activity for dummy surface! Consider specifying " 453227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "your own SurfaceView!"); 454227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 455227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return dummySurfaceView; 456227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 457227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 458227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Activity findActivityForContext(Context context) { 459227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return (context instanceof Activity) ? (Activity) context : null; 460227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 461227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 462227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @TargetApi(11) 463227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void maybeDestroyRenderScript() { 464227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mRenderScript != null) { 465227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mRenderScript.destroy(); 466227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mRenderScript = null; 467227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 468227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 469227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 470227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks} 471