165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/* 265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project 365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License"); 565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License. 665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at 765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * http://www.apache.org/licenses/LICENSE-2.0 965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software 1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS, 1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and 1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License. 1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpackage android.filterfw.core; 1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.FilterContext; 2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.FilterPort; 2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.KeyValueMap; 2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.io.TextGraphReader; 2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.io.GraphIOException; 2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.format.ObjectFormat; 2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.util.Log; 2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.io.Serializable; 2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.lang.annotation.Annotation; 3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.lang.reflect.Field; 3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.lang.Thread; 3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.Collection; 3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.HashMap; 3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.HashSet; 3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.Map.Entry; 3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.LinkedList; 3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport java.util.Set; 3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/** 4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @hide 4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpublic abstract class Filter { 4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static final int STATUS_PREINIT = 0; 4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static final int STATUS_UNPREPARED = 1; 4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static final int STATUS_PREPARED = 2; 4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static final int STATUS_PROCESSING = 3; 4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static final int STATUS_SLEEPING = 4; 4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static final int STATUS_FINISHED = 5; 5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static final int STATUS_ERROR = 6; 5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static final int STATUS_RELEASED = 7; 5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private String mName; 5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private int mInputCount = -1; 5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private int mOutputCount = -1; 5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private HashMap<String, InputPort> mInputPorts; 5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private HashMap<String, OutputPort> mOutputPorts; 6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private HashSet<Frame> mFramesToRelease; 6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private HashMap<String, Frame> mFramesToSet; 6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private int mStatus = 0; 6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private boolean mIsOpen = false; 6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private int mSleepDelay; 6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private long mCurrentTimestamp; 6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private boolean mLogVerbose; 7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private static final String TAG = "Filter"; 7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public Filter(String name) { 7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mName = name; 7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mFramesToRelease = new HashSet<Frame>(); 7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mFramesToSet = new HashMap<String, Frame>(); 7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mStatus = STATUS_PREINIT; 7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); 8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** Tests to see if a given filter is installed on the system. Requires 8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * full filter package name, including filterpack. 8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public static final boolean isAvailable(String filterName) { 8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); 8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Class filterClass; 8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // First see if a class of that name exists 8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn try { 9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn filterClass = contextClassLoader.loadClass(filterName); 9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } catch (ClassNotFoundException e) { 9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Then make sure it's a subclass of Filter. 9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn try { 9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn filterClass.asSubclass(Filter.class); 9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } catch (ClassCastException e) { 9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final void initWithValueMap(KeyValueMap valueMap) { 10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Initialization 10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn initFinalPorts(valueMap); 10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Setup remaining ports 10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn initRemainingPorts(valueMap); 10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // This indicates that final ports can no longer be set 11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mStatus = STATUS_UNPREPARED; 11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final void initWithAssignmentString(String assignments) { 11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn try { 11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn KeyValueMap valueMap = new TextGraphReader().readKeyValueAssignments(assignments); 11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn initWithValueMap(valueMap); 11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } catch (GraphIOException e) { 11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new IllegalArgumentException(e.getMessage()); 12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final void initWithAssignmentList(Object... keyValues) { 12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn KeyValueMap valueMap = new KeyValueMap(); 12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn valueMap.setKeyValues(keyValues); 12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn initWithValueMap(valueMap); 12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final void init() throws ProtocolException { 13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn KeyValueMap valueMap = new KeyValueMap(); 13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn initWithValueMap(valueMap); 13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public String getFilterClassName() { 13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return getClass().getSimpleName(); 13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final String getName() { 13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mName; 14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public boolean isOpen() { 14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mIsOpen; 14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void setInputFrame(String inputName, Frame frame) { 14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FilterPort port = getInputPort(inputName); 14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!port.isOpen()) { 14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn port.open(); 15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn port.setFrame(frame); 15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final void setInputValue(String inputName, Object value) { 15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setInputFrame(inputName, wrapInputValue(inputName, value)); 15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void prepare(FilterContext context) { 15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void parametersUpdated(Set<String> updated) { 16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void delayNextProcess(int millisecs) { 16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mSleepDelay = millisecs; 16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mStatus = STATUS_SLEEPING; 16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public abstract void setupPorts(); 17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public FrameFormat getOutputFormat(String portName, FrameFormat inputFormat) { 17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return null; 17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final FrameFormat getInputFormat(String portName) { 17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn InputPort inputPort = getInputPort(portName); 17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return inputPort.getSourceFormat(); 17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void open(FilterContext context) { 18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public abstract void process(FilterContext context); 18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final int getSleepDelay() { 18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return 250; 18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void close(FilterContext context) { 19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void tearDown(FilterContext context) { 19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final int getNumberOfConnectedInputs() { 19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int c = 0; 19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (InputPort inputPort : mInputPorts.values()) { 19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (inputPort.isConnected()) { 19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ++c; 20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return c; 20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final int getNumberOfConnectedOutputs() { 20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int c = 0; 20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (OutputPort outputPort : mOutputPorts.values()) { 20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (outputPort.isConnected()) { 20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ++c; 21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return c; 21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final int getNumberOfInputs() { 21665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mOutputPorts == null ? 0 : mInputPorts.size(); 21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final int getNumberOfOutputs() { 22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mInputPorts == null ? 0 : mOutputPorts.size(); 22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final InputPort getInputPort(String portName) { 22465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mInputPorts == null) { 22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new NullPointerException("Attempting to access input port '" + portName 22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn + "' of " + this + " before Filter has been initialized!"); 22765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn InputPort result = mInputPorts.get(portName); 22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result == null) { 23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new IllegalArgumentException("Unknown input port '" + portName + "' on filter " 23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn + this + "!"); 23265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 23465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public final OutputPort getOutputPort(String portName) { 23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mInputPorts == null) { 23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new NullPointerException("Attempting to access output port '" + portName 23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn + "' of " + this + " before Filter has been initialized!"); 24065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn OutputPort result = mOutputPorts.get(portName); 24265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result == null) { 24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new IllegalArgumentException("Unknown output port '" + portName + "' on filter " 24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn + this + "!"); 24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 24865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected final void pushOutput(String name, Frame frame) { 25065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (frame.getTimestamp() == Frame.TIMESTAMP_NOT_SET) { 25165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Default-setting output Frame timestamp on port " + name + " to " + mCurrentTimestamp); 25265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn frame.setTimestamp(mCurrentTimestamp); 25365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn getOutputPort(name).pushFrame(frame); 25565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 25765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected final Frame pullInput(String name) { 25865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Frame result = getInputPort(name).pullFrame(); 25965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mCurrentTimestamp == Frame.TIMESTAMP_UNKNOWN) { 26065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mCurrentTimestamp = result.getTimestamp(); 26165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Default-setting current timestamp from input port " + name + " to " + mCurrentTimestamp); 26265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 26365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // As result is retained, we add it to the release pool here 26465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mFramesToRelease.add(result); 26565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 26765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 26865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public void fieldPortValueUpdated(String name, FilterContext context) { 27065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 27165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 27265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 27365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Transfers any frame from an input port to its destination. This is useful to force a 27465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * transfer from a FieldPort or ProgramPort to its connected target (field or program variable). 27565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 27665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void transferInputPortFrame(String name, FilterContext context) { 27765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn getInputPort(name).transfer(context); 27865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 27965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 28065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 28165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Assigns all program variables to the ports they are connected to. Call this after 28265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * constructing a Program instance with attached ProgramPorts. 28365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 28465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void initProgramInputs(Program program, FilterContext context) { 28565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (program != null) { 28665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (InputPort inputPort : mInputPorts.values()) { 28765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (inputPort.getTarget() == program) { 28865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn inputPort.transfer(context); 28965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 29465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 29565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Adds an input port to the filter. You should call this from within setupPorts, if your 29665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * filter has input ports. No type-checking is performed on the input. If you would like to 29765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * check against a type mask, use 29865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * {@link #addMaskedInputPort(String, FrameFormat) addMaskedInputPort} instead. 29965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 30065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param name the name of the input port 30165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 30265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void addInputPort(String name) { 30365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addMaskedInputPort(name, null); 30465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 30565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 30665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 30765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Adds an input port to the filter. You should call this from within setupPorts, if your 30865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * filter has input ports. When type-checking is performed, the input format is 30965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * checked against the provided format mask. An exception is thrown in case of a conflict. 31065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 31165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param name the name of the input port 31265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param formatMask a format mask, which filters the allowable input types 31365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 31465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void addMaskedInputPort(String name, FrameFormat formatMask) { 31565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn InputPort port = new StreamPort(this, name); 31665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + port); 31765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mInputPorts.put(name, port); 31865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn port.setPortFormat(formatMask); 31965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 32065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 32165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 32265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Adds an output port to the filter with a fixed output format. You should call this from 32365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * within setupPorts, if your filter has output ports. You cannot use this method, if your 32465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * output format depends on the input format (e.g. in a pass-through filter). In this case, use 32565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * {@link #addOutputBasedOnInput(String, String) addOutputBasedOnInput} instead. 32665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 32765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param name the name of the output port 32865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param format the fixed output format of this port 32965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 33065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void addOutputPort(String name, FrameFormat format) { 33165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn OutputPort port = new OutputPort(this, name); 33265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + port); 33365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn port.setPortFormat(format); 33465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mOutputPorts.put(name, port); 33565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 33665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 33765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 33865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Adds an output port to the filter. You should call this from within setupPorts, if your 33965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * filter has output ports. Using this method indicates that the output format for this 34065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * particular port, depends on the format of an input port. You MUST also override 34165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * {@link #getOutputFormat(String, FrameFormat) getOutputFormat} to specify what format your 34265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * filter will output for a given input. If the output format of your filter port does not 34365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * depend on the input, use {@link #addOutputPort(String, FrameFormat) addOutputPort} instead. 34465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 34565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param outputName the name of the output port 34665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param inputName the name of the input port, that this output depends on 34765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 34865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void addOutputBasedOnInput(String outputName, String inputName) { 34965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn OutputPort port = new OutputPort(this, outputName); 35065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + port); 35165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn port.setBasePort(getInputPort(inputName)); 35265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mOutputPorts.put(outputName, port); 35365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 35465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 35565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void addFieldPort(String name, 35665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Field field, 35765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn boolean hasDefault, 35865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn boolean isFinal) { 35965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Make sure field is accessible 36065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn field.setAccessible(true); 36165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 36265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create port for this input 36365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn InputPort fieldPort = isFinal 36465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ? new FinalPort(this, name, field, hasDefault) 36565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn : new FieldPort(this, name, field, hasDefault); 36665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 36765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create format for this input 36865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + fieldPort); 36965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn MutableFrameFormat format = ObjectFormat.fromClass(field.getType(), 37065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FrameFormat.TARGET_SIMPLE); 37165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn fieldPort.setPortFormat(format); 37265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 37365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Add port 37465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mInputPorts.put(name, fieldPort); 37565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 37665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 37765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void addProgramPort(String name, 37865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn String varName, 37965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Field field, 38065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Class varType, 38165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn boolean hasDefault) { 38265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Make sure field is accessible 38365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn field.setAccessible(true); 38465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 38565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create port for this input 38665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn InputPort programPort = new ProgramPort(this, name, varName, field, hasDefault); 38765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 38865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create format for this input 38965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + programPort); 39065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn MutableFrameFormat format = ObjectFormat.fromClass(varType, 39165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FrameFormat.TARGET_SIMPLE); 39265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn programPort.setPortFormat(format); 39365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 39465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Add port 39565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mInputPorts.put(name, programPort); 39665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 39765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 39865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void closeOutputPort(String name) { 39965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn getOutputPort(name).close(); 40065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 40165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 40265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 40365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Specifies whether the filter should not be scheduled until a frame is available on that 40465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * input port. Note, that setting this to false, does not block a new frame from coming in 40565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * (though there is no necessity to pull that frame for processing). 40665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param portName the name of the input port. 40765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param waits true, if the filter should wait for a frame on this port. 40865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 40965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void setWaitsOnInputPort(String portName, boolean waits) { 41065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn getInputPort(portName).setBlocking(waits); 41165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 41265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 41365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn /** 41465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Specifies whether the filter should not be scheduled until the output port is free, i.e. 41565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * there is no frame waiting on that output. 41665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param portName the name of the output port. 41765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @param waits true, if the filter should wait for the port to become free. 41865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 41965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn protected void setWaitsOnOutputPort(String portName, boolean waits) { 42065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn getOutputPort(portName).setBlocking(waits); 42165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 42265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 42365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public String toString() { 42465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return "'" + getName() + "' (" + getFilterClassName() + ")"; 42565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 42665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 42765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Core internal methods /////////////////////////////////////////////////////////////////////// 42865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final Collection<InputPort> getInputPorts() { 42965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mInputPorts.values(); 43065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 43165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 43265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final Collection<OutputPort> getOutputPorts() { 43365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mOutputPorts.values(); 43465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 43565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 43665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final synchronized int getStatus() { 43765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return mStatus; 43865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 43965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 44065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final synchronized void unsetStatus(int flag) { 44165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mStatus &= ~flag; 44265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 44365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 44465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final synchronized void performOpen(FilterContext context) { 44565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!mIsOpen) { 44665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mStatus == STATUS_UNPREPARED) { 44765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Preparing " + this); 44865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn prepare(context); 44965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mStatus = STATUS_PREPARED; 45065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 45165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mStatus == STATUS_PREPARED) { 45265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Opening " + this); 45365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn open(context); 45465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mStatus = STATUS_PROCESSING; 45565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 45665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mStatus != STATUS_PROCESSING) { 45765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("Filter " + this + " was brought into invalid state during " 45865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn + "opening (state: " + mStatus + ")!"); 45965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 46065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mIsOpen = true; 46165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 46265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 46365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 46465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final synchronized void performProcess(FilterContext context) { 46565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mStatus == STATUS_RELEASED) { 46665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("Filter " + this + " is already torn down!"); 46765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 46865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn transferInputFrames(context); 46965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mStatus < STATUS_PROCESSING) { 47065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn performOpen(context); 47165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 47265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Processing " + this); 47365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mCurrentTimestamp = Frame.TIMESTAMP_UNKNOWN; 47465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn process(context); 47565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn releasePulledFrames(context); 47665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (filterMustClose()) { 47765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn performClose(context); 47865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 47965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 48065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 48165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final synchronized void performClose(FilterContext context) { 48265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mIsOpen) { 48365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Closing " + this); 48465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mIsOpen = false; 48565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mStatus = STATUS_PREPARED; 48665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn close(context); 48765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn closePorts(); 48865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 48965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 49065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 49165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final synchronized void performTearDown(FilterContext context) { 49265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn performClose(context); 49365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mStatus != STATUS_RELEASED) { 49465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn tearDown(context); 49565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mStatus = STATUS_RELEASED; 49665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 49765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 49865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 49965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn synchronized final boolean canProcess() { 50065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Checking if can process: " + this + " (" + mStatus + ")."); 50165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mStatus <= STATUS_PROCESSING) { 50265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return inputConditionsMet() && outputConditionsMet(); 50365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else { 50465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 50565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 50665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 50765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 50865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final void openOutputs() { 50965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Opening all output ports on " + this + "!"); 51065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (OutputPort outputPort : mOutputPorts.values()) { 51165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!outputPort.isOpen()) { 51265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn outputPort.open(); 51365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 51465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 51565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 51665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 51765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final void clearInputs() { 51865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (InputPort inputPort : mInputPorts.values()) { 51965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn inputPort.clear(); 52065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 52165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 52265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 52365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final void clearOutputs() { 52465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (OutputPort outputPort : mOutputPorts.values()) { 52565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn outputPort.clear(); 52665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 52765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 52865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 52965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final void notifyFieldPortValueUpdated(String name, FilterContext context) { 53065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mStatus == STATUS_PROCESSING || mStatus == STATUS_PREPARED) { 53165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn fieldPortValueUpdated(name, context); 53265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 53365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 53465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 53565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final synchronized void pushInputFrame(String inputName, Frame frame) { 53665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FilterPort port = getInputPort(inputName); 53765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!port.isOpen()) { 53865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn port.open(); 53965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 54065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn port.pushFrame(frame); 54165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 54265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 54365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn final synchronized void pushInputValue(String inputName, Object value) { 54465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn pushInputFrame(inputName, wrapInputValue(inputName, value)); 54565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 54665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 54765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Filter internal methods ///////////////////////////////////////////////////////////////////// 54865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void initFinalPorts(KeyValueMap values) { 54965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mInputPorts = new HashMap<String, InputPort>(); 55065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mOutputPorts = new HashMap<String, OutputPort>(); 55165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addAndSetFinalPorts(values); 55265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 55365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 55465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void initRemainingPorts(KeyValueMap values) { 55565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addAnnotatedPorts(); 55665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setupPorts(); // TODO: rename to addFilterPorts() ? 55765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setInitialInputValues(values); 55865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 55965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 56065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void addAndSetFinalPorts(KeyValueMap values) { 56165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Class filterClass = getClass(); 56265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Annotation annotation; 56365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (Field field : filterClass.getDeclaredFields()) { 56465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if ((annotation = field.getAnnotation(GenerateFinalPort.class)) != null) { 56565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GenerateFinalPort generator = (GenerateFinalPort)annotation; 56665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn String name = generator.name().isEmpty() ? field.getName() : generator.name(); 56765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn boolean hasDefault = generator.hasDefault(); 56865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addFieldPort(name, field, hasDefault, true); 56965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (values.containsKey(name)) { 57065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setImmediateInputValue(name, values.get(name)); 57165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn values.remove(name); 57265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else if (!generator.hasDefault()) { 57365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn throw new RuntimeException("No value specified for final input port '" 57465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn + name + "' of filter " + this + "!"); 57565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 57665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 57765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 57865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 57965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 58065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void addAnnotatedPorts() { 58165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Class filterClass = getClass(); 58265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Annotation annotation; 58365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (Field field : filterClass.getDeclaredFields()) { 58465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if ((annotation = field.getAnnotation(GenerateFieldPort.class)) != null) { 58565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GenerateFieldPort generator = (GenerateFieldPort)annotation; 58665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addFieldGenerator(generator, field); 58765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else if ((annotation = field.getAnnotation(GenerateProgramPort.class)) != null) { 58865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GenerateProgramPort generator = (GenerateProgramPort)annotation; 58965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addProgramGenerator(generator, field); 59065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else if ((annotation = field.getAnnotation(GenerateProgramPorts.class)) != null) { 59165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GenerateProgramPorts generators = (GenerateProgramPorts)annotation; 59265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (GenerateProgramPort generator : generators.value()) { 59365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addProgramGenerator(generator, field); 59465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 59565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 59665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 59765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 59865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 59965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void addFieldGenerator(GenerateFieldPort generator, Field field) { 60065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn String name = generator.name().isEmpty() ? field.getName() : generator.name(); 60165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn boolean hasDefault = generator.hasDefault(); 60265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addFieldPort(name, field, hasDefault, false); 60365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 60465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 60565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void addProgramGenerator(GenerateProgramPort generator, Field field) { 60665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn String name = generator.name(); 60765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn String varName = generator.variableName().isEmpty() ? name 60865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn : generator.variableName(); 60965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Class varType = generator.type(); 61065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn boolean hasDefault = generator.hasDefault(); 61165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn addProgramPort(name, varName, field, varType, hasDefault); 61265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 61365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 61465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void setInitialInputValues(KeyValueMap values) { 61565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (Entry<String, Object> entry : values.entrySet()) { 61665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn setInputValue(entry.getKey(), entry.getValue()); 61765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 61865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 61965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 62065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void setImmediateInputValue(String name, Object value) { 62165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Setting immediate value " + value + " for port " + name + "!"); 62265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FilterPort port = getInputPort(name); 62365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn port.open(); 62465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn port.setFrame(SimpleFrame.wrapObject(value, null)); 62565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 62665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 62765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void transferInputFrames(FilterContext context) { 62865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (InputPort inputPort : mInputPorts.values()) { 62965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn inputPort.transfer(context); 63065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 63165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 63265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 63365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final Frame wrapInputValue(String inputName, Object value) { 63465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn MutableFrameFormat inputFormat = ObjectFormat.fromObject(value, FrameFormat.TARGET_SIMPLE); 63565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (value == null) { 63665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // If the value is null, the format cannot guess the class, so we adjust it to the 63765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // class of the input port here 63865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FrameFormat portFormat = getInputPort(inputName).getPortFormat(); 63965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Class portClass = (portFormat == null) ? null : portFormat.getObjectClass(); 64065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn inputFormat.setObjectClass(portClass); 64165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 64265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 64365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Serialize if serializable, and type is not an immutable primitive. 64465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn boolean shouldSerialize = !(value instanceof Number) 64565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn && !(value instanceof Boolean) 64665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn && !(value instanceof String) 64765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn && value instanceof Serializable; 64865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 64965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create frame wrapper 65065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn Frame frame = shouldSerialize 65165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ? new SerializedFrame(inputFormat, null) 65265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn : new SimpleFrame(inputFormat, null); 65365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn frame.setObjectValue(value); 65465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return frame; 65565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 65665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 65765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void releasePulledFrames(FilterContext context) { 65865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (Frame frame : mFramesToRelease) { 65965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn context.getFrameManager().releaseFrame(frame); 66065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 66165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn mFramesToRelease.clear(); 66265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 66365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 66465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final boolean inputConditionsMet() { 66565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (FilterPort port : mInputPorts.values()) { 66665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!port.isReady()) { 66765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Input condition not met: " + port + "!"); 66865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 66965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 67065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 67165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 67265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 67365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 67465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final boolean outputConditionsMet() { 67565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (FilterPort port : mOutputPorts.values()) { 67665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!port.isReady()) { 67765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Output condition not met: " + port + "!"); 67865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 67965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 68065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 68165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 68265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 68365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 68465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final void closePorts() { 68565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Closing all ports on " + this + "!"); 68665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (InputPort inputPort : mInputPorts.values()) { 68765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn inputPort.close(); 68865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 68965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (OutputPort outputPort : mOutputPorts.values()) { 69065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn outputPort.close(); 69165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 69265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 69365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 69465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private final boolean filterMustClose() { 69565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (InputPort inputPort : mInputPorts.values()) { 69665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (inputPort.filterMustClose()) { 69765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Filter " + this + " must close due to port " + inputPort); 69865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 69965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 70065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 70165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (OutputPort outputPort : mOutputPorts.values()) { 70265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (outputPort.filterMustClose()) { 70365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mLogVerbose) Log.v(TAG, "Filter " + this + " must close due to port " + outputPort); 70465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 70565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 70665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 70765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 70865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 70965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 710