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.os.SystemClock; 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.ArrayList; 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.HashMap; 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.Map; 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.concurrent.atomic.AtomicBoolean; 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/** 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Filters are the processing nodes of the filter graphs. 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Filters may have any number of input and output ports, through which the data frames flow. 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * TODO: More documentation on filter life-cycle, port and type checking, GL and RenderScript, ... 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic abstract class Filter { 33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static class State { 35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static final int STATE_UNPREPARED = 1; 36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static final int STATE_PREPARED = 2; 37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static final int STATE_OPEN = 3; 38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static final int STATE_CLOSED = 4; 39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static final int STATE_DESTROYED = 5; 40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public int current = STATE_UNPREPARED; 42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public synchronized boolean check(int state) { 44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return current == state; 45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private final int REQUEST_FLAG_NONE = 0; 50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private final int REQUEST_FLAG_CLOSE = 1; 51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mName; 53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private MffContext mContext; 54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private FilterGraph mFilterGraph; 55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private State mState = new State(); 57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private int mRequests = REQUEST_FLAG_NONE; 58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private int mMinimumAvailableInputs = 1; 60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private int mMinimumAvailableOutputs = 1; 61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private int mScheduleCount = 0; 63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private long mLastScheduleTime = 0; 64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mIsActive = true; 66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private AtomicBoolean mIsSleeping = new AtomicBoolean(false); 67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private long mCurrentTimestamp = Frame.TIMESTAMP_NOT_SET; 69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private HashMap<String, InputPort> mConnectedInputPorts = new HashMap<String, InputPort>(); 71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private HashMap<String, OutputPort> mConnectedOutputPorts = new HashMap<String, OutputPort>(); 72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private InputPort[] mConnectedInputPortArray = null; 74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private OutputPort[] mConnectedOutputPortArray = null; 75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private ArrayList<Frame> mAutoReleaseFrames = new ArrayList<Frame>(); 77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Constructs a new filter. 81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * A filter is bound to a specific MffContext. Its name can be any String value, but it must 82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * be unique within the filter graph. 83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Note that names starting with "$" are reserved for internal use, and should not be used. 85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param context The MffContext in which the filter will live. 87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param name The name of the filter. 88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected Filter(MffContext context, String name) { 90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mName = name; 91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mContext = context; 92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Checks whether the filter class is available on this platform. 96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Some filters may not be installed on all platforms and can therefore not be instantiated. 97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Before instantiating a filter, check if it is available by using this method. 98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This method uses the shared FilterFactory to check whether the filter class is available. 100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param filterClassName The fully qualified class name of the Filter class. 102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if filters of the specified class name are available. 103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static final boolean isAvailable(String filterClassName) { 105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return FilterFactory.sharedFactory().isFilterAvailable(filterClassName); 106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the name of this filter. 110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the name of the filter (specified during construction). 112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public String getName() { 114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mName; 115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the signature of this filter. 119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Subclasses should override this and return their filter signature. The default 121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * implementation returns a generic signature with no constraints. 122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This method may be called at any time. 124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the Signature instance for this filter. 126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public Signature getSignature() { 128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return new Signature(); 129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the MffContext that the filter resides in. 133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the MffContext of the filter. 135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public MffContext getContext() { 137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mContext; 138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns true, if the filter is active. 142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * TODO: thread safety? 143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if the filter is active. 145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean isActive() { 147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mIsActive; 148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Activates the current filter. 152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Only active filters can be scheduled for execution. This method can only be called if the 153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * GraphRunner that is executing the filter is stopped or paused. 154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void activate() { 156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertIsPaused(); 157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!mIsActive) { 158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mIsActive = true; 159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Deactivates the current filter. 164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Only active filters can be scheduled for execution. This method can only be called if the 165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * GraphRunner that is executing the filter is stopped or paused. 166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void deactivate() { 168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // TODO: Support close-on-deactivate (must happen in processing thread). 169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertIsPaused(); 170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mIsActive) { 171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mIsActive = false; 172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 173227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 174227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 175227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 176227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the filter's set of input ports. 177227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Note that this contains only the *connected* input ports. To retrieve all 178227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * input ports that this filter accepts, one has to go via the filter's Signature. 179227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 180227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return An array containing all connected input ports. 181227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 182227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final InputPort[] getConnectedInputPorts() { 183227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mConnectedInputPortArray; 184227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 185227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 186227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 187227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the filter's set of output ports. 188227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Note that this contains only the *connected* output ports. To retrieve all 189227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * output ports that this filter provides, one has to go via the filter's Signature. 190227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 191227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return An array containing all connected output ports. 192227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 193227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final OutputPort[] getConnectedOutputPorts() { 194227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mConnectedOutputPortArray; 195227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 196227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 197227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 198227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the input port with the given name. 199227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Note that this can only access the *connected* input ports. To retrieve all 200227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * input ports that this filter accepts, one has to go via the filter's Signature. 201227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 202227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the input port with the specified name, or null if no connected input port 203227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * with this name exists. 204227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 205227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final InputPort getConnectedInputPort(String name) { 206227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mConnectedInputPorts.get(name); 207227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 208227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 209227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 210227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the output port with the given name. 211227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Note that this can only access the *connected* output ports. To retrieve all 212227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * output ports that this filter provides, one has to go via the filter's Signature. 213227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 214227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the output port with the specified name, or null if no connected output port 215227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * with this name exists. 216227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 217227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final OutputPort getConnectedOutputPort(String name) { 218227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mConnectedOutputPorts.get(name); 219227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 220227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 221227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 222227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Called when an input port has been attached in the graph. 223227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Override this method, in case you want to be informed of any connected input ports, or make 224227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * modifications to them. Note that you may not assume that any other ports have been attached 225227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * already. If you have dependencies on other ports, override 226227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #onInputPortOpen(InputPort)}. The default implementation does nothing. 227227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 228227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param port The InputPort instance that was attached. 229227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 230227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected void onInputPortAttached(InputPort port) { 231227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 232227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 233227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 234227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Called when an output port has been attached in the graph. 235227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Override this method, in case you want to be informed of any connected output ports, or make 236227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * modifications to them. Note that you may not assume that any other ports have been attached 237227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * already. If you have dependencies on other ports, override 238227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #onOutputPortOpen(OutputPort)}. The default implementation does nothing. 239227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 240227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param port The OutputPort instance that was attached. 241227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 242227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected void onOutputPortAttached(OutputPort port) { 243227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 244227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 245227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 246227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Called when an input port is opened on this filter. 247227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Input ports are opened by the data produce, that is the filter that is connected to an 248227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * input port. Override this if you need to make modifications to the port before processing 249227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * begins. Note, that this is only called if the connected filter is scheduled. You may assume 250227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * that all ports are attached when this is called. 251227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 252227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param port The InputPort instance that was opened. 253227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 254227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected void onInputPortOpen(InputPort port) { 255227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 256227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 257227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 258227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Called when an output port is opened on this filter. 259227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Output ports are opened when the filter they are attached to is opened. Override this if you 260227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * need to make modifications to the port before processing begins. Note, that this is only 261227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * called if the filter is scheduled. You may assume that all ports are attached when this is 262227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * called. 263227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 264227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param port The OutputPort instance that was opened. 265227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 266227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected void onOutputPortOpen(OutputPort port) { 267227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 268227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 269227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 270227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns true, if the filter is currently open. 271227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if the filter is currently open. 272227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 273227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final boolean isOpen() { 274227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mState.check(State.STATE_OPEN); 275227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 276227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 277227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 278227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public String toString() { 279227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mName + " (" + getClass().getSimpleName() + ")"; 280227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 281227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 282227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 283227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Called when filter is prepared. 284227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Subclasses can override this to prepare the filter for processing. This method gets called 285227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * once only just before the filter is scheduled for processing the first time. 286227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 287227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #onTearDown() 288227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 289227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected void onPrepare() { 290227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 291227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 292227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 293227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Called when the filter is opened. 294227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Subclasses can override this to perform any kind of initialization just before processing 295227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * starts. This method may be called any number of times, but is always balanced with an 296227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #onClose()} call. 297227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 298227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #onClose() 299227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 300227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected void onOpen() { 301227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 302227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 303227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 304227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Called to perform processing on Frame data. 305227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is the only method subclasses must override. It is called every time the filter is 306227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * ready for processing. Typically this is when there is input data to process and available 307227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * output ports, but may differ depending on the port configuration. 308227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 309227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected abstract void onProcess(); 310227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 311227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 312227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Called when the filter is closed. 313227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Subclasses can override this to perform any kind of post-processing steps. Processing will 314227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * not resume until {@link #onOpen()} is called again. This method is only called if the filter 315227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * is open. 316227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 317227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #onOpen() 318227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 319227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected void onClose() { 320227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 321227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 322227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 323227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Called when the filter is torn down. 324227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Subclasses can override this to perform clean-up tasks just before the filter is disposed of. 325227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * It is called when the filter graph that the filter belongs to is disposed. 326227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 327227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #onPrepare() 328227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 329227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected void onTearDown() { 330227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 331227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 332227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 333227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Check if the input conditions are met in order to schedule this filter. 334227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 335227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is used by {@link #canSchedule()} to determine if the input-port conditions given by 336227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * the filter are met. Subclasses that override scheduling behavior can make use of this 337227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * function. 338227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 339227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if the filter's input conditions are met. 340227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 341227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected boolean inputConditionsMet() { 342227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mConnectedInputPortArray.length > 0) { 343227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int inputFrames = 0; 344227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // [Non-iterator looping] 345227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (int i = 0; i < mConnectedInputPortArray.length; ++i) { 346227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!mConnectedInputPortArray[i].conditionsMet()) { 347227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return false; 348227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (mConnectedInputPortArray[i].hasFrame()) { 349227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ++inputFrames; 350227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 351227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 352227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (inputFrames < mMinimumAvailableInputs) { 353227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return false; 354227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 355227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 356227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return true; 357227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 358227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 359227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 360227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Check if the output conditions are met in order to schedule this filter. 361227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 362227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is used by {@link #canSchedule()} to determine if the output-port conditions given by 363227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * the filter are met. Subclasses that override scheduling behavior can make use of this 364227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * function. 365227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 366227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if the filter's output conditions are met. 367227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 368227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected boolean outputConditionsMet() { 369227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mConnectedOutputPortArray.length > 0) { 370227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int availableOutputs = 0; 371227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (int i = 0; i < mConnectedOutputPortArray.length; ++i) { 372227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!mConnectedOutputPortArray[i].conditionsMet()) { 373227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return false; 374227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (mConnectedOutputPortArray[i].isAvailable()) { 375227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ++availableOutputs; 376227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 377227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 378227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (availableOutputs < mMinimumAvailableOutputs) { 379227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return false; 380227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 381227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 382227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return true; 383227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 384227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 385227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 386227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Check if the Filter is in a state so that it can be scheduled. 387227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 388227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * When overriding the filter's {@link #canSchedule()} method, you should never allow 389227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * scheduling a filter that is not in a schedulable state. This will result in undefined 390227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * behavior. 391227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 392227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if the filter is in a schedulable state. 393227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 394227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected boolean inSchedulableState() { 395227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return (mIsActive && !mState.check(State.STATE_CLOSED)); 396227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 397227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 398227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 399227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns true if the filter can be currently scheduled. 400227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 401227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Filters may override this method if they depend on custom factors that determine whether 402227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * they can be scheduled or not. The scheduler calls this method to determine whether or not 403227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * a filter can be scheduled for execution. It does not guarantee that it will be executed. 404227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * It is strongly recommended to call super's implementation to make sure your filter can be 405227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * scheduled based on its state, input and output ports. 406227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 407227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if the filter can be scheduled. 408227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 409227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected boolean canSchedule() { 410227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return inSchedulableState() && inputConditionsMet() && outputConditionsMet(); 411227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 412227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 413227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 414227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the current FrameManager instance. 415227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the current FrameManager instance or null if there is no FrameManager set up yet. 416227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 417227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final FrameManager getFrameManager() { 418227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mFilterGraph.mRunner != null ? mFilterGraph.mRunner.getFrameManager() : null; 419227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 420227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 421227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 422227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns whether the GraphRunner for this filter is running. 423227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 424227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Generally, this method should not be used for performing operations that need to be carried 425227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * out before running begins. Use {@link #performPreparation(Runnable)} for this. 426227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 427227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if the GraphRunner for this filter is running. 428227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 429227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final boolean isRunning() { 430227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mFilterGraph != null && mFilterGraph.mRunner != null 431227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks && mFilterGraph.mRunner.isRunning(); 432227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 433227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 434227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 435227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Performs operations before the filter is running. 436227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 437227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Use this method when your filter requires to perform operations while the graph is not 438227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * running. The filter will not be scheduled for execution until your method has completed 439227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * execution. 440227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 441227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final boolean performPreparation(Runnable runnable) { 442227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mState) { 443227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current == State.STATE_OPEN) { 444227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return false; 445227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 446227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks runnable.run(); 447227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return true; 448227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 449227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 450227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 451227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 452227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 453227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Request that this filter be closed after the current processing step. 454227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 455227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Implementations may call this within their {@link #onProcess()} calls to indicate that the 456227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * filter is done processing and wishes to be closed. After such a request the filter will be 457227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * closed and no longer receive {@link #onProcess()} calls. 458227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 459227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #onClose() 460227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #onProcess() 461227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 462227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final void requestClose() { 463227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mRequests |= REQUEST_FLAG_CLOSE; 464227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 465227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 466227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 467227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Sets the minimum number of input frames required to process. 468227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * A filter will not be scheduled unless at least a certain number of input frames are available 469227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * on the input ports. This is only relevant if the filter has input ports and is not waiting on 470227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * all ports. 471227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * The default value is 1. 472227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 473227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param count the minimum number of frames required to process. 474227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #getMinimumAvailableInputs() 475227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #setMinimumAvailableOutputs(int) 476227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see InputPort#setWaitsForFrame(boolean) 477227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 478227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final void setMinimumAvailableInputs(int count) { 479227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mMinimumAvailableInputs = count; 480227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 481227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 482227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 483227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the minimum number of input frames required to process this filter. 484227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * The default value is 1. 485227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 486227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the minimum number of input frames required to process. 487227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #setMinimumAvailableInputs(int) 488227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 489227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final int getMinimumAvailableInputs() { 490227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mMinimumAvailableInputs; 491227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 492227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 493227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 494227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Sets the minimum number of available output ports required to process. 495227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * A filter will not be scheduled unless atleast a certain number of output ports are available. 496227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is only relevant if the filter has output ports and is not waiting on all ports. The 497227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * default value is 1. 498227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 499227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param count the minimum number of frames required to process. 500227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #getMinimumAvailableOutputs() 501227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #setMinimumAvailableInputs(int) 502227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see OutputPort#setWaitsUntilAvailable(boolean) 503227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 504227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final void setMinimumAvailableOutputs(int count) { 505227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mMinimumAvailableOutputs = count; 506227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 507227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 508227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 509227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the minimum number of available outputs required to process this filter. 510227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * The default value is 1. 511227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 512227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the minimum number of available outputs required to process. 513227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #setMinimumAvailableOutputs(int) 514227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 515227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final int getMinimumAvailableOutputs() { 516227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mMinimumAvailableOutputs; 517227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 518227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 519227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 520227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Puts the filter to sleep so that it is no longer scheduled. 521227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * To resume scheduling the filter another thread must call wakeUp() on this filter. 522227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 523227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final void enterSleepState() { 524227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mIsSleeping.set(true); 525227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 526227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 527227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 528227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Wakes the filter and resumes scheduling. 529227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is generally called from another thread to signal that this filter should resume 530227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * processing. Does nothing if filter is not sleeping. 531227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 532227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final void wakeUp() { 533227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mIsSleeping.getAndSet(false)) { 534227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (isRunning()) { 535227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilterGraph.mRunner.signalWakeUp(); 536227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 537227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 538227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 539227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 540227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 541227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns whether this Filter is allowed to use OpenGL. 542227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 543227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Filters may use OpenGL if the MffContext supports OpenGL and its GraphRunner allows it. 544227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 545227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if this Filter is allowed to use OpenGL. 546227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 547227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected final boolean isOpenGLSupported() { 548227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mFilterGraph.mRunner.isOpenGLSupported(); 549227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 550227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 551227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 552227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Connect an output port to an input port of another filter. 553227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Connects the output port with the specified name to the input port with the specified name 554227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * of the specified filter. If the input or output ports do not exist already, they are 555227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * automatically created and added to the respective filter. 556227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 557227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void connect(String outputName, Filter targetFilter, String inputName) { 558227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Make sure not connected already 559227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (getConnectedOutputPort(outputName) != null) { 560227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Attempting to connect already connected output port '" 561227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + outputName + "' of filter " + this + "'!"); 562227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (targetFilter.getConnectedInputPort(inputName) != null) { 563227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Attempting to connect already connected input port '" 564227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + inputName + "' of filter " + targetFilter + "'!"); 565227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 566227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 567227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Establish connection 568227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks InputPort inputPort = targetFilter.newInputPort(inputName); 569227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks OutputPort outputPort = newOutputPort(outputName); 570227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks outputPort.setTarget(inputPort); 571227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 572227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Fire attachment callbacks 573227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks targetFilter.onInputPortAttached(inputPort); 574227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks onOutputPortAttached(outputPort); 575227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 576227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Update array of ports (which is maintained for more efficient access) 577227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks updatePortArrays(); 578227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 579227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 580227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final Map<String, InputPort> getConnectedInputPortMap() { 581227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mConnectedInputPorts; 582227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 583227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 584227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final Map<String, OutputPort> getConnectedOutputPortMap() { 585227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mConnectedOutputPorts; 586227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 587227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 588227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void execute() { 589227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mState) { 590227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks autoPullInputs(); 591227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mLastScheduleTime = SystemClock.elapsedRealtime(); 592227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current == State.STATE_UNPREPARED) { 593227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks onPrepare(); 594227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mState.current = State.STATE_PREPARED; 595227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 596227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current == State.STATE_PREPARED) { 597227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks openPorts(); 598227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks onOpen(); 599227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mState.current = State.STATE_OPEN; 600227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 601227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current == State.STATE_OPEN) { 602227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks onProcess(); 603227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mRequests != REQUEST_FLAG_NONE) { 604227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks processRequests(); 605227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 606227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 607227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 608227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks autoReleaseFrames(); 609227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ++mScheduleCount; 610227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 611227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 612227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void performClose() { 613227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mState) { 614227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current == State.STATE_OPEN) { 615227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks onClose(); 616227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mIsSleeping.set(false); 617227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mState.current = State.STATE_CLOSED; 618227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCurrentTimestamp = Frame.TIMESTAMP_NOT_SET; 619227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 620227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 621227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 622227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 623227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void softReset() { 624227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mState) { 625227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks performClose(); 626227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current == State.STATE_CLOSED) { 627227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mState.current = State.STATE_PREPARED; 628227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 629227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 630227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 631227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 632227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void performTearDown() { 633227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mState) { 634227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mState.current == State.STATE_OPEN) { 635227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Attempting to tear-down filter " + this + " which is " 636227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "in an open state!"); 637227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (mState.current != State.STATE_DESTROYED 638227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks && mState.current != State.STATE_UNPREPARED) { 639227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks onTearDown(); 640227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mState.current = State.STATE_DESTROYED; 641227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 642227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 643227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 644227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 645227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void insertIntoFilterGraph(FilterGraph graph) { 646227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilterGraph = graph; 647227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks updatePortArrays(); 648227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 649227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 650227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final int getScheduleCount() { 651227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mScheduleCount; 652227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 653227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 654227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void resetScheduleCount() { 655227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mScheduleCount = 0; 656227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 657227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 658227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void openPorts() { 659227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Opening the output ports will open the connected input ports 660227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (OutputPort outputPort : mConnectedOutputPorts.values()) { 661227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks openOutputPort(outputPort); 662227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 663227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 664227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 665227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void addAutoReleaseFrame(Frame frame) { 666227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mAutoReleaseFrames.add(frame); 667227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 668227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 669227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final long getCurrentTimestamp() { 670227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mCurrentTimestamp; 671227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 672227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 673227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void onPulledFrameWithTimestamp(long timestamp) { 674227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (timestamp > mCurrentTimestamp || mCurrentTimestamp == Frame.TIMESTAMP_NOT_SET) { 675227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCurrentTimestamp = timestamp; 676227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 677227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 678227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 679227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void openOutputPort(OutputPort outPort) { 680227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (outPort.getQueue() == null) { 681227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks try { 682227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameQueue.Builder builder = new FrameQueue.Builder(); 683227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks InputPort inPort = outPort.getTarget(); 684227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks outPort.onOpen(builder); 685227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks inPort.onOpen(builder); 686227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Filter targetFilter = inPort.getFilter(); 687227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks String queueName = mName + "[" + outPort.getName() + "] -> " + targetFilter.mName 688227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "[" + inPort.getName() + "]"; 689227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameQueue queue = builder.build(queueName); 690227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks outPort.setQueue(queue); 691227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks inPort.setQueue(queue); 692227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } catch (RuntimeException e) { 693227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Could not open output port " + outPort + "!", e); 694227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 695227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 696227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 697227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 698227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final boolean isSleeping() { 699227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mIsSleeping.get(); 700227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 701227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 702227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final long getLastScheduleTime() { 703227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mLastScheduleTime ; 704227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 705227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 706227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private final void autoPullInputs() { 707227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // [Non-iterator looping] 708227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (int i = 0; i < mConnectedInputPortArray.length; ++i) { 709227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks InputPort port = mConnectedInputPortArray[i]; 710227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (port.hasFrame() && port.isAutoPullEnabled()) { 711227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mConnectedInputPortArray[i].pullFrame(); 712227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 713227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 714227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 715227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 716227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private final void autoReleaseFrames() { 717227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // [Non-iterator looping] 718227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (int i = 0; i < mAutoReleaseFrames.size(); ++i) { 719227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mAutoReleaseFrames.get(i).release(); 720227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 721227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mAutoReleaseFrames.clear(); 722227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 723227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 724227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private final InputPort newInputPort(String name) { 725227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks InputPort result = mConnectedInputPorts.get(name); 726227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (result == null) { 727227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Signature.PortInfo info = getSignature().getInputPortInfo(name); 728227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result = new InputPort(this, name, info); 729227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mConnectedInputPorts.put(name, result); 730227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 731227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return result; 732227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 733227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 734227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private final OutputPort newOutputPort(String name) { 735227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks OutputPort result = mConnectedOutputPorts.get(name); 736227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (result == null) { 737227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Signature.PortInfo info = getSignature().getOutputPortInfo(name); 738227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result = new OutputPort(this, name, info); 739227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mConnectedOutputPorts.put(name, result); 740227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 741227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return result; 742227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 743227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 744227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private final void processRequests() { 745227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if ((mRequests & REQUEST_FLAG_CLOSE) != 0) { 746227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks performClose(); 747227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mRequests = REQUEST_FLAG_NONE; 748227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 749227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 750227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 751227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void assertIsPaused() { 752227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GraphRunner runner = GraphRunner.current(); 753227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (runner != null && !runner.isPaused() && !runner.isStopped()) { 754227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Attempting to modify filter state while runner is " 755227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "executing. Please pause or stop the runner first!"); 756227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 757227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 758227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 759227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private final void updatePortArrays() { 760227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Copy our port-maps to arrays for faster non-iterator access 761227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mConnectedInputPortArray = mConnectedInputPorts.values().toArray(new InputPort[0]); 762227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mConnectedOutputPortArray = mConnectedOutputPorts.values().toArray(new OutputPort[0]); 763227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 764227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 765227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks} 766227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 767