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 java.lang.reflect.Field; 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/** 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Input ports are the receiving ports of frames in a filter. 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <p> 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * InputPort instances receive Frame data from connected OutputPort instances of a previous filter. 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Frames flow from output ports to input ports. Filters can process frame data by calling 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #pullFrame()} on an input port. If the input port is set to wait for an input frame 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * (see {@link #setWaitsForFrame(boolean)}), there is guaranteed to be Frame on the port before 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@code onProcess()} is called. This is the default setting. Otherwise, calling 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #pullFrame()} may return a value of {@code null}. 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <p/><p> 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * InputPorts may be bound to fields of the Filter. When an input port is bound to a field, Frame 32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * values will be assigned to the field once a Frame is received on that port. The Frame value must 33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * be of a type that is compatible with the field type. 34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * </p> 35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic final class InputPort { 37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Filter mFilter; 39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mName; 40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Signature.PortInfo mInfo; 41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private FrameListener mListener = null; 42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private FrameQueue.Builder mQueueBuilder = null; 43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private FrameQueue mQueue = null; 44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mWaitForFrame = true; 45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mAutoPullEnabled = false; 46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public interface FrameListener { 48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void onFrameReceived(InputPort port, Frame frame); 49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private class FieldBinding implements FrameListener { 52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Field mField; 53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public FieldBinding(Field field) { 55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mField = field; 56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void onFrameReceived(InputPort port, Frame frame) { 60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks try { 61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if(port.mInfo.type.getNumberOfDimensions() > 0) { 62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameValues frameValues = frame.asFrameValues(); 63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mField.set(mFilter, frameValues.getValues()); 64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameValue frameValue = frame.asFrameValue(); 66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mField.set(mFilter, frameValue.getValue()); 67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } catch (Exception e) { 69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Assigning frame " + frame + " to field " 70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + mField + " of filter " + mFilter + " caused exception!", e); 71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Attach this input port to an output port for frame passing. 77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Use this method whenever you plan on passing a Frame through from an input port to an 79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * output port. This must be called from inside 80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link Filter#onInputPortAttached(InputPort) onInputPortAttached}. 81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param outputPort the output port that Frames will be pushed to. 83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void attachToOutputPort(OutputPort outputPort) { 85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertInAttachmentStage(); 86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilter.openOutputPort(outputPort); 87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueueBuilder.attachQueue(outputPort.getQueue()); 88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Bind this input port to the specified listener. 92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Use this when you wish to be notified of incoming frames. The listener method 94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link FrameListener#onFrameReceived(InputPort, Frame)} will be called once a Frame is pulled 95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * on this port. Typically this is called from inside 96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link Filter#onInputPortAttached(InputPort) onInputPortAttached}, and used in 97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * conjunction with {@link #setAutoPullEnabled(boolean)}. Overrides any previous bindings. 98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param listener the listener to handle incoming Frames. 100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void bindToListener(FrameListener listener) { 102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertInAttachmentStage(); 103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mListener = listener; 104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Bind this input port to the specified field. 108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Use this when you wish to pull frames directly into a field of the filter. This requires 110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * that the input frames can be interpreted as object-based frames of the field's class. 111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Overrides any previous bindings. 112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is typically called from inside 114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link Filter#onInputPortAttached(InputPort) onInputPortAttached}, and used in 115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * conjunction with {@link #setAutoPullEnabled(boolean)}. 116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param field the field to pull frame data into. 118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #bindToFieldNamed(String) 119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #setAutoPullEnabled(boolean) 120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void bindToField(Field field) { 122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks assertInAttachmentStage(); 123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mListener = new FieldBinding(field); 124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Bind this input port to the field with the specified name. 128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Use this when you wish to pull frames directly into a field of the filter. This requires 130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * that the input frames can be interpreted as object-based frames of the field's class. 131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Overrides any previous bindings. 132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is typically called from inside 134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link Filter#onInputPortAttached(InputPort) onInputPortAttached}, and used in 135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * conjunction with {@link #setAutoPullEnabled(boolean)}. 136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param fieldName the field to pull frame data into. 138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #bindToField(Field) 139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #setAutoPullEnabled(boolean) 140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void bindToFieldNamed(String fieldName) { 142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Field field = findFieldNamed(fieldName, mFilter.getClass()); 143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (field == null) { 144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IllegalArgumentException("Attempting to bind to unknown field '" 145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + fieldName + "'!"); 146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks bindToField(field); 148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Set whether the InputPort automatically pulls frames. 152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is typically only used when the port is bound to another target. 153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param enabled true, if frames should be automatically pulled on this port. 154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void setAutoPullEnabled(boolean enabled) { 156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mAutoPullEnabled = enabled; 157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns whether the InputPort automatically pulls frames. 161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if frames are automatically pulled on this port. 162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean isAutoPullEnabled() { 164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mAutoPullEnabled; 165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Pull a waiting a frame from the port. 169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Call this to pull a frame from the input port for processing. If no frame is waiting on the 171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * input port, returns null. After this call the port will have no Frame waiting (empty port). 172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Note, that this returns a frame owned by the input queue. You must detach the frame if you 173227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * wish to hold on to it. 174227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 175227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return Frame instance, or null if no frame is available for pulling. 176227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 177227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public synchronized Frame pullFrame() { 178227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mQueue == null) { 179227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IllegalStateException("Cannot pull frame from closed input port!"); 180227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 181227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Frame frame = mQueue.pullFrame(); 182227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (frame != null) { 183227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mListener != null) { 184227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mListener.onFrameReceived(this, frame); 185227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 186227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks //Log.i("InputPort", "Adding frame " + frame + " to auto-release pool"); 187227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilter.addAutoReleaseFrame(frame); 188227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks long timestamp = frame.getTimestamp(); 189227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (timestamp != Frame.TIMESTAMP_NOT_SET) { 190227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilter.onPulledFrameWithTimestamp(frame.getTimestamp()); 191227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 192227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 193227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return frame; 194227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 195227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 196227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public synchronized Frame peek() { 197227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mQueue == null) { 198227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IllegalStateException("Cannot pull frame from closed input port!"); 199227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 200227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mQueue.peek(); 201227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 202227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 203227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 204227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns true, if the port is connected. 205227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if there is an output port that connects to this port. 206227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 207227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean isConnected() { 208227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mQueue != null; 209227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 210227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 211227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 212227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns true, if there is a frame waiting on this port. 213227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if there is a frame waiting on this port. 214227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 215227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public synchronized boolean hasFrame() { 216227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mQueue != null && mQueue.canPull(); 217227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 218227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 219227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 220227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Sets whether to wait for a frame on this port before processing. 221227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * When set to true, the Filter will not be scheduled for processing unless there is a Frame 222227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * waiting on this port. The default value is true. 223227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 224227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param wait true, if the Filter should wait for a Frame before processing. 225227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #waitsForFrame() 226227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 227227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void setWaitsForFrame(boolean wait) { 228227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mWaitForFrame = wait; 229227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 230227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 231227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 232227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns whether the filter waits for a frame on this port before processing. 233227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if the filter waits for a frame on this port before processing. 234227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #setWaitsForFrame(boolean) 235227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 236227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean waitsForFrame() { 237227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mWaitForFrame; 238227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 239227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 240227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 241227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the input port's name. 242227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is the name that was specified when the input port was connected. 243227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 244227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the input port's name. 245227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 246227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public String getName() { 247227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mName; 248227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 249227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 250227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 251227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the FrameType of this port. 252227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is the type that was specified when the input port was declared. 253227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 254227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the input port's FrameType. 255227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 256227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public FrameType getType() { 257227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return getQueue().getType(); 258227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 259227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 260227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 261227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Return the filter object that this port belongs to. 262227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 263227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the input port's filter. 264227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 265227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public Filter getFilter() { 266227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mFilter; 267227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 268227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 269227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 270227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public String toString() { 271227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mFilter.getName() + ":" + mName; 272227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 273227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 274227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Internal only /////////////////////////////////////////////////////////////////////////////// 275227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks InputPort(Filter filter, String name, Signature.PortInfo info) { 276227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilter = filter; 277227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mName = name; 278227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mInfo = info; 279227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 280227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 281227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks boolean conditionsMet() { 282227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return !mWaitForFrame || hasFrame(); 283227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 284227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 285227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void onOpen(FrameQueue.Builder builder) { 286227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueueBuilder = builder; 287227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueueBuilder.setReadType(mInfo.type); 288227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilter.onInputPortOpen(this); 289227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 290227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 291227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void setQueue(FrameQueue queue) { 292227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueue = queue; 293227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueueBuilder = null; 294227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 295227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 296227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameQueue getQueue() { 297227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mQueue; 298227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 299227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 300227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void clear() { 301227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mQueue != null) { 302227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueue.clear(); 303227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 304227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 305227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 306227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void assertInAttachmentStage() { 307227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mQueueBuilder == null) { 308227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IllegalStateException("Attempting to attach port while not in attachment " 309227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "stage!"); 310227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 311227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 312227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 313227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Field findFieldNamed(String fieldName, Class<?> clazz) { 314227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Field field = null; 315227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks try { 316227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks field = clazz.getDeclaredField(fieldName); 317227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks field.setAccessible(true); 318227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } catch (NoSuchFieldException e) { 319227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Class<?> superClass = clazz.getSuperclass(); 320227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (superClass != null) { 321227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks field = findFieldNamed(fieldName, superClass); 322227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 323227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 324227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return field; 325227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 326227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks} 327227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 328