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