130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni/* 230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Copyright (C) 2011 The Android Open Source Project 330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * 430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Licensed under the Apache License, Version 2.0 (the "License"); 530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * you may not use this file except in compliance with the License. 630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * You may obtain a copy of the License at 730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * 830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * http://www.apache.org/licenses/LICENSE-2.0 930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * 1030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Unless required by applicable law or agreed to in writing, software 1130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * distributed under the License is distributed on an "AS IS" BASIS, 1230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * See the License for the specific language governing permissions and 1430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * limitations under the License. 1530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni */ 1630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 1730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 1830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronipackage android.filterfw.core; 1930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 20692c3bf7a1c7e2d5b1066cf7a1b057e993742c87Marius Rennimport android.filterfw.core.FilterContext; 2130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniimport android.filterfw.core.FilterPort; 2230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniimport android.filterfw.core.KeyValueMap; 23c0017fd82acec5d0427306ea5f536c3d78854f95Marius Rennimport android.filterfw.io.TextGraphReader; 24c0017fd82acec5d0427306ea5f536c3d78854f95Marius Rennimport android.filterfw.io.GraphIOException; 2521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Rennimport android.filterfw.format.ObjectFormat; 2621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Rennimport android.util.Log; 2730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 287eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Rennimport java.io.Serializable; 29c0017fd82acec5d0427306ea5f536c3d78854f95Marius Rennimport java.lang.annotation.Annotation; 30c0017fd82acec5d0427306ea5f536c3d78854f95Marius Rennimport java.lang.reflect.Field; 31f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvalaimport java.lang.Thread; 3221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Rennimport java.util.Collection; 3330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniimport java.util.HashMap; 3430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniimport java.util.HashSet; 35c0017fd82acec5d0427306ea5f536c3d78854f95Marius Rennimport java.util.Map.Entry; 3630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniimport java.util.LinkedList; 3730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniimport java.util.Set; 3830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 39a3bfbe5389c6146abe318a7add3fa688d69bc01bEino-Ville Talvala/** 40a3bfbe5389c6146abe318a7add3fa688d69bc01bEino-Ville Talvala * @hide 41a3bfbe5389c6146abe318a7add3fa688d69bc01bEino-Ville Talvala */ 4230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronipublic abstract class Filter { 4330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 4421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn static final int STATUS_PREINIT = 0; 4521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn static final int STATUS_UNPREPARED = 1; 468541cea20c74fdfe35a6c63c09459dd969292b7eMarius Renn static final int STATUS_PREPARED = 2; 4721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn static final int STATUS_PROCESSING = 3; 4821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn static final int STATUS_SLEEPING = 4; 4921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn static final int STATUS_FINISHED = 5; 5021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn static final int STATUS_ERROR = 6; 51c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua static final int STATUS_RELEASED = 7; 5230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 5330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni private String mName; 5430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 5530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni private int mInputCount = -1; 5630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni private int mOutputCount = -1; 5730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 58f24dc0f733da39b32f15177871a79810d52e6212Marius Renn private HashMap<String, InputPort> mInputPorts; 59f24dc0f733da39b32f15177871a79810d52e6212Marius Renn private HashMap<String, OutputPort> mOutputPorts; 6030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 6121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private HashSet<Frame> mFramesToRelease; 6221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private HashMap<String, Frame> mFramesToSet; 6330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 6430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni private int mStatus = 0; 6530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni private boolean mIsOpen = false; 6621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private int mSleepDelay; 6730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 685b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala private long mCurrentTimestamp; 695b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala 7057774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala private boolean mLogVerbose; 710c60e0ab6013df46586bcb6c26f48a850f4c7115Eino-Ville Talvala private static final String TAG = "Filter"; 7257774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala 7330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni public Filter(String name) { 7430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni mName = name; 7521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mFramesToRelease = new HashSet<Frame>(); 7621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mFramesToSet = new HashMap<String, Frame>(); 7721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mStatus = STATUS_PREINIT; 7857774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala 7957774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); 8030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 8130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 82f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala /** Tests to see if a given filter is installed on the system. Requires 83f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala * full filter package name, including filterpack. 84f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala */ 85f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala public static final boolean isAvailable(String filterName) { 86f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); 87f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala Class filterClass; 88f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala // First see if a class of that name exists 89f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala try { 90f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala filterClass = contextClassLoader.loadClass(filterName); 91f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala } catch (ClassNotFoundException e) { 92f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala return false; 93f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala } 94f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala // Then make sure it's a subclass of Filter. 95f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala try { 96f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala filterClass.asSubclass(Filter.class); 97f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala } catch (ClassCastException e) { 98f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala return false; 99f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala } 100f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala return true; 101f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala } 102f9ffc783f43d3092223a1827fec1b95490e3d743Eino-Ville Talvala 10321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final void initWithValueMap(KeyValueMap valueMap) { 10421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Initialization 10521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn initFinalPorts(valueMap); 10621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 10721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Setup remaining ports 10821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn initRemainingPorts(valueMap); 10921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 11021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // This indicates that final ports can no longer be set 11121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mStatus = STATUS_UNPREPARED; 11230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 11330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 11421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final void initWithAssignmentString(String assignments) { 115c0017fd82acec5d0427306ea5f536c3d78854f95Marius Renn try { 11621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn KeyValueMap valueMap = new TextGraphReader().readKeyValueAssignments(assignments); 11721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn initWithValueMap(valueMap); 118c0017fd82acec5d0427306ea5f536c3d78854f95Marius Renn } catch (GraphIOException e) { 119c0017fd82acec5d0427306ea5f536c3d78854f95Marius Renn throw new IllegalArgumentException(e.getMessage()); 120c0017fd82acec5d0427306ea5f536c3d78854f95Marius Renn } 12130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 12230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 12321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final void initWithAssignmentList(Object... keyValues) { 12421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn KeyValueMap valueMap = new KeyValueMap(); 12521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn valueMap.setKeyValues(keyValues); 12621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn initWithValueMap(valueMap); 12730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 12830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 12930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni public final void init() throws ProtocolException { 13021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn KeyValueMap valueMap = new KeyValueMap(); 13121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn initWithValueMap(valueMap); 13230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 13330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 13430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni public String getFilterClassName() { 13530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return getClass().getSimpleName(); 13630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 13730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 13830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni public final String getName() { 13930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return mName; 14030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 14130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 14230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni public boolean isOpen() { 14330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return mIsOpen; 14430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 14530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 146f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn public void setInputFrame(String inputName, Frame frame) { 14721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn FilterPort port = getInputPort(inputName); 14821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (!port.isOpen()) { 14921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn port.open(); 150c0017fd82acec5d0427306ea5f536c3d78854f95Marius Renn } 15121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn port.setFrame(frame); 15230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 15330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 15421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final void setInputValue(String inputName, Object value) { 155f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn setInputFrame(inputName, wrapInputValue(inputName, value)); 15630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 15730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 158692c3bf7a1c7e2d5b1066cf7a1b057e993742c87Marius Renn protected void prepare(FilterContext context) { 15930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 16030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 16130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni protected void parametersUpdated(Set<String> updated) { 16230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 16330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 16421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected void delayNextProcess(int millisecs) { 16521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mSleepDelay = millisecs; 16621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mStatus = STATUS_SLEEPING; 16721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 16830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 16921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public abstract void setupPorts(); 17030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 17121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public FrameFormat getOutputFormat(String portName, FrameFormat inputFormat) { 17221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return null; 173b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn } 174b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn 17521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final FrameFormat getInputFormat(String portName) { 176f24dc0f733da39b32f15177871a79810d52e6212Marius Renn InputPort inputPort = getInputPort(portName); 17721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return inputPort.getSourceFormat(); 17821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 179692c3bf7a1c7e2d5b1066cf7a1b057e993742c87Marius Renn 18021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public void open(FilterContext context) { 18130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 18230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 18321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public abstract void process(FilterContext context); 18430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 18521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final int getSleepDelay() { 18630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return 250; 18730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 18830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 189692c3bf7a1c7e2d5b1066cf7a1b057e993742c87Marius Renn public void close(FilterContext context) { 19030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 19130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 192692c3bf7a1c7e2d5b1066cf7a1b057e993742c87Marius Renn public void tearDown(FilterContext context) { 19330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 19430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 19521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final int getNumberOfConnectedInputs() { 19621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn int c = 0; 197f24dc0f733da39b32f15177871a79810d52e6212Marius Renn for (InputPort inputPort : mInputPorts.values()) { 19821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (inputPort.isConnected()) { 19921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn ++c; 20021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 20130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 20221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return c; 20330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 20430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 20521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final int getNumberOfConnectedOutputs() { 20621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn int c = 0; 207f24dc0f733da39b32f15177871a79810d52e6212Marius Renn for (OutputPort outputPort : mOutputPorts.values()) { 20821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (outputPort.isConnected()) { 20921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn ++c; 21021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 21130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 21221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return c; 21330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 21430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 21521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final int getNumberOfInputs() { 21621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return mOutputPorts == null ? 0 : mInputPorts.size(); 21721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 21821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 21921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public final int getNumberOfOutputs() { 22021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return mInputPorts == null ? 0 : mOutputPorts.size(); 22121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 22221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 223f24dc0f733da39b32f15177871a79810d52e6212Marius Renn public final InputPort getInputPort(String portName) { 224cfda0a38d6f394724e0cbd831ec9bc71d951fc74Marius Renn if (mInputPorts == null) { 225cfda0a38d6f394724e0cbd831ec9bc71d951fc74Marius Renn throw new NullPointerException("Attempting to access input port '" + portName 226cfda0a38d6f394724e0cbd831ec9bc71d951fc74Marius Renn + "' of " + this + " before Filter has been initialized!"); 227cfda0a38d6f394724e0cbd831ec9bc71d951fc74Marius Renn } 228f24dc0f733da39b32f15177871a79810d52e6212Marius Renn InputPort result = mInputPorts.get(portName); 229b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn if (result == null) { 230b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn throw new IllegalArgumentException("Unknown input port '" + portName + "' on filter " 231b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn + this + "!"); 232b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn } 233b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn return result; 23430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 23530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 236f24dc0f733da39b32f15177871a79810d52e6212Marius Renn public final OutputPort getOutputPort(String portName) { 237cfda0a38d6f394724e0cbd831ec9bc71d951fc74Marius Renn if (mInputPorts == null) { 238cfda0a38d6f394724e0cbd831ec9bc71d951fc74Marius Renn throw new NullPointerException("Attempting to access output port '" + portName 239cfda0a38d6f394724e0cbd831ec9bc71d951fc74Marius Renn + "' of " + this + " before Filter has been initialized!"); 240cfda0a38d6f394724e0cbd831ec9bc71d951fc74Marius Renn } 241f24dc0f733da39b32f15177871a79810d52e6212Marius Renn OutputPort result = mOutputPorts.get(portName); 242b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn if (result == null) { 243b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn throw new IllegalArgumentException("Unknown output port '" + portName + "' on filter " 244b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn + this + "!"); 245b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn } 246b64fe6f6bbad306e4b10fafefcbdd981ec82a5baMarius Renn return result; 24730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 24830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 24921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected final void pushOutput(String name, Frame frame) { 2505b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala if (frame.getTimestamp() == Frame.TIMESTAMP_NOT_SET) { 2515b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Default-setting output Frame timestamp on port " + name + " to " + mCurrentTimestamp); 2525b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala frame.setTimestamp(mCurrentTimestamp); 2535b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala } 25421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn getOutputPort(name).pushFrame(frame); 25530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 25630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 25721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected final Frame pullInput(String name) { 25821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn Frame result = getInputPort(name).pullFrame(); 2595b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala if (mCurrentTimestamp == Frame.TIMESTAMP_UNKNOWN) { 2605b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala mCurrentTimestamp = result.getTimestamp(); 261d0d514c296daba245f4c70871f1a1db39535f87cEino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Default-setting current timestamp from input port " + name + " to " + mCurrentTimestamp); 2625b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala } 26321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // As result is retained, we add it to the release pool here 26421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mFramesToRelease.add(result); 26530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 26630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return result; 26730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 26830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 26921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public void fieldPortValueUpdated(String name, FilterContext context) { 27021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 27121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 27221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn /** 27316c2d40d344a19b7d85777b5c71c1102db48769eMarius Renn * Transfers any frame from an input port to its destination. This is useful to force a 27416c2d40d344a19b7d85777b5c71c1102db48769eMarius Renn * transfer from a FieldPort or ProgramPort to its connected target (field or program variable). 27516c2d40d344a19b7d85777b5c71c1102db48769eMarius Renn */ 27616c2d40d344a19b7d85777b5c71c1102db48769eMarius Renn protected void transferInputPortFrame(String name, FilterContext context) { 27716c2d40d344a19b7d85777b5c71c1102db48769eMarius Renn getInputPort(name).transfer(context); 27816c2d40d344a19b7d85777b5c71c1102db48769eMarius Renn } 27916c2d40d344a19b7d85777b5c71c1102db48769eMarius Renn 28016c2d40d344a19b7d85777b5c71c1102db48769eMarius Renn /** 2813f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn * Assigns all program variables to the ports they are connected to. Call this after 2823f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn * constructing a Program instance with attached ProgramPorts. 2833f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn */ 2843f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn protected void initProgramInputs(Program program, FilterContext context) { 2853f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn if (program != null) { 2863f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn for (InputPort inputPort : mInputPorts.values()) { 2873f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn if (inputPort.getTarget() == program) { 2883f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn inputPort.transfer(context); 2893f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn } 2903f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn } 2913f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn } 2923f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn } 2933f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn 2943f7ca5db73a94285e404e09d377dd5fd6afc7aafMarius Renn /** 29521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * Adds an input port to the filter. You should call this from within setupPorts, if your 29621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * filter has input ports. No type-checking is performed on the input. If you would like to 29721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * check against a type mask, use 29821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * {@link #addMaskedInputPort(String, FrameFormat) addMaskedInputPort} instead. 29921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * 30021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * @param name the name of the input port 30121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn */ 30221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected void addInputPort(String name) { 30321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addMaskedInputPort(name, null); 30421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 30521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 30621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn /** 30721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * Adds an input port to the filter. You should call this from within setupPorts, if your 30821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * filter has input ports. When type-checking is performed, the input format is 30921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * checked against the provided format mask. An exception is thrown in case of a conflict. 31021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * 31121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * @param name the name of the input port 31221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * @param formatMask a format mask, which filters the allowable input types 31321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn */ 31421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected void addMaskedInputPort(String name, FrameFormat formatMask) { 315f24dc0f733da39b32f15177871a79810d52e6212Marius Renn InputPort port = new StreamPort(this, name); 31657774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + port); 31721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mInputPorts.put(name, port); 31821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn port.setPortFormat(formatMask); 31921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 32021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 32121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn /** 32221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * Adds an output port to the filter with a fixed output format. You should call this from 32321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * within setupPorts, if your filter has output ports. You cannot use this method, if your 32421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * output format depends on the input format (e.g. in a pass-through filter). In this case, use 32521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * {@link #addOutputBasedOnInput(String, String) addOutputBasedOnInput} instead. 32621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * 32721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * @param name the name of the output port 32821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * @param format the fixed output format of this port 32921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn */ 33021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected void addOutputPort(String name, FrameFormat format) { 33121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn OutputPort port = new OutputPort(this, name); 33257774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + port); 33321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn port.setPortFormat(format); 33421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mOutputPorts.put(name, port); 33521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 33621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 33721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn /** 33821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * Adds an output port to the filter. You should call this from within setupPorts, if your 33921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * filter has output ports. Using this method indicates that the output format for this 34021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * particular port, depends on the format of an input port. You MUST also override 34121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * {@link #getOutputFormat(String, FrameFormat) getOutputFormat} to specify what format your 34221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * filter will output for a given input. If the output format of your filter port does not 34321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * depend on the input, use {@link #addOutputPort(String, FrameFormat) addOutputPort} instead. 34421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * 34521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * @param outputName the name of the output port 34621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn * @param inputName the name of the input port, that this output depends on 34721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn */ 34821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected void addOutputBasedOnInput(String outputName, String inputName) { 34921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn OutputPort port = new OutputPort(this, outputName); 35057774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + port); 35121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn port.setBasePort(getInputPort(inputName)); 35221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mOutputPorts.put(outputName, port); 35321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 35421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 35521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected void addFieldPort(String name, 35621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn Field field, 35721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn boolean hasDefault, 35821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn boolean isFinal) { 35921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Make sure field is accessible 36021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn field.setAccessible(true); 36121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 36221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Create port for this input 363f24dc0f733da39b32f15177871a79810d52e6212Marius Renn InputPort fieldPort = isFinal 36421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn ? new FinalPort(this, name, field, hasDefault) 36521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn : new FieldPort(this, name, field, hasDefault); 36621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 36721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Create format for this input 36857774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + fieldPort); 36921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn MutableFrameFormat format = ObjectFormat.fromClass(field.getType(), 370bf4aaebc555cfb1e49ee411e3477203749fe6a11Marius Renn FrameFormat.TARGET_SIMPLE); 37121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn fieldPort.setPortFormat(format); 37221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 37321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Add port 37421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mInputPorts.put(name, fieldPort); 37521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 37621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 37721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected void addProgramPort(String name, 37821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn String varName, 37921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn Field field, 38021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn Class varType, 38121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn boolean hasDefault) { 38221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Make sure field is accessible 38321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn field.setAccessible(true); 38421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 38521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Create port for this input 386f24dc0f733da39b32f15177871a79810d52e6212Marius Renn InputPort programPort = new ProgramPort(this, name, varName, field, hasDefault); 38721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 38821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Create format for this input 38957774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Filter " + this + " adding " + programPort); 39021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn MutableFrameFormat format = ObjectFormat.fromClass(varType, 391bf4aaebc555cfb1e49ee411e3477203749fe6a11Marius Renn FrameFormat.TARGET_SIMPLE); 39221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn programPort.setPortFormat(format); 39321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 39421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Add port 39521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mInputPorts.put(name, programPort); 39621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 39721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 39821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn protected void closeOutputPort(String name) { 39921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn getOutputPort(name).close(); 40021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 40121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 40248189dec808108f392000edbdc90bbd6b1818671Marius Renn /** 40348189dec808108f392000edbdc90bbd6b1818671Marius Renn * Specifies whether the filter should not be scheduled until a frame is available on that 40448189dec808108f392000edbdc90bbd6b1818671Marius Renn * input port. Note, that setting this to false, does not block a new frame from coming in 40548189dec808108f392000edbdc90bbd6b1818671Marius Renn * (though there is no necessity to pull that frame for processing). 40648189dec808108f392000edbdc90bbd6b1818671Marius Renn * @param portName the name of the input port. 40748189dec808108f392000edbdc90bbd6b1818671Marius Renn * @param waits true, if the filter should wait for a frame on this port. 40848189dec808108f392000edbdc90bbd6b1818671Marius Renn */ 40948189dec808108f392000edbdc90bbd6b1818671Marius Renn protected void setWaitsOnInputPort(String portName, boolean waits) { 41048189dec808108f392000edbdc90bbd6b1818671Marius Renn getInputPort(portName).setBlocking(waits); 411c0017fd82acec5d0427306ea5f536c3d78854f95Marius Renn } 412c0017fd82acec5d0427306ea5f536c3d78854f95Marius Renn 41348189dec808108f392000edbdc90bbd6b1818671Marius Renn /** 41448189dec808108f392000edbdc90bbd6b1818671Marius Renn * Specifies whether the filter should not be scheduled until the output port is free, i.e. 41548189dec808108f392000edbdc90bbd6b1818671Marius Renn * there is no frame waiting on that output. 41648189dec808108f392000edbdc90bbd6b1818671Marius Renn * @param portName the name of the output port. 41748189dec808108f392000edbdc90bbd6b1818671Marius Renn * @param waits true, if the filter should wait for the port to become free. 41848189dec808108f392000edbdc90bbd6b1818671Marius Renn */ 41948189dec808108f392000edbdc90bbd6b1818671Marius Renn protected void setWaitsOnOutputPort(String portName, boolean waits) { 42048189dec808108f392000edbdc90bbd6b1818671Marius Renn getOutputPort(portName).setBlocking(waits); 421c0017fd82acec5d0427306ea5f536c3d78854f95Marius Renn } 422c0017fd82acec5d0427306ea5f536c3d78854f95Marius Renn 42330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni public String toString() { 42430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return "'" + getName() + "' (" + getFilterClassName() + ")"; 42530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 42630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 42730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Core internal methods /////////////////////////////////////////////////////////////////////// 428f24dc0f733da39b32f15177871a79810d52e6212Marius Renn final Collection<InputPort> getInputPorts() { 42921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return mInputPorts.values(); 43021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 43121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 432f24dc0f733da39b32f15177871a79810d52e6212Marius Renn final Collection<OutputPort> getOutputPorts() { 43321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return mOutputPorts.values(); 43430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 43530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 43621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn final synchronized int getStatus() { 43721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return mStatus; 43830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 43930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 44030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni final synchronized void unsetStatus(int flag) { 44130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni mStatus &= ~flag; 44230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 44330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 44421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn final synchronized void performOpen(FilterContext context) { 44521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (!mIsOpen) { 44621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (mStatus == STATUS_UNPREPARED) { 44757774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Preparing " + this); 44821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn prepare(context); 4498541cea20c74fdfe35a6c63c09459dd969292b7eMarius Renn mStatus = STATUS_PREPARED; 45021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 4518541cea20c74fdfe35a6c63c09459dd969292b7eMarius Renn if (mStatus == STATUS_PREPARED) { 45257774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Opening " + this); 45321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn open(context); 45421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mStatus = STATUS_PROCESSING; 45521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 45621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (mStatus != STATUS_PROCESSING) { 45721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn throw new RuntimeException("Filter " + this + " was brought into invalid state during " 45821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn + "opening (state: " + mStatus + ")!"); 45921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 46021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mIsOpen = true; 46130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 46230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 46330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 46421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn final synchronized void performProcess(FilterContext context) { 465c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua if (mStatus == STATUS_RELEASED) { 466c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua throw new RuntimeException("Filter " + this + " is already torn down!"); 467c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua } 46821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn transferInputFrames(context); 46921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (mStatus < STATUS_PROCESSING) { 47021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn performOpen(context); 47121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 47257774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Processing " + this); 4735b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala mCurrentTimestamp = Frame.TIMESTAMP_UNKNOWN; 47421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn process(context); 47521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn releasePulledFrames(context); 47621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (filterMustClose()) { 47721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn performClose(context); 47830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 47930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 48030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 48121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn final synchronized void performClose(FilterContext context) { 48221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (mIsOpen) { 48357774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Closing " + this); 48430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni mIsOpen = false; 4858541cea20c74fdfe35a6c63c09459dd969292b7eMarius Renn mStatus = STATUS_PREPARED; 486692c3bf7a1c7e2d5b1066cf7a1b057e993742c87Marius Renn close(context); 48721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn closePorts(); 48830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 48930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 49030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 491c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua final synchronized void performTearDown(FilterContext context) { 492c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua performClose(context); 493c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua if (mStatus != STATUS_RELEASED) { 494c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua tearDown(context); 495c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua mStatus = STATUS_RELEASED; 496c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua } 497c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua } 498c64256d3d005329f36ea0d618ec5b5a6c8bab7d1Wei Hua 49930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni synchronized final boolean canProcess() { 500489c240d3ae33e83dc62ea6f3cc864e47c0e2e3bMarius Renn if (mLogVerbose) Log.v(TAG, "Checking if can process: " + this + " (" + mStatus + ")."); 50121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (mStatus <= STATUS_PROCESSING) { 50221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return inputConditionsMet() && outputConditionsMet(); 50321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } else { 50430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 50530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 50621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 50730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 5088541cea20c74fdfe35a6c63c09459dd969292b7eMarius Renn final void openOutputs() { 50957774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Opening all output ports on " + this + "!"); 510f24dc0f733da39b32f15177871a79810d52e6212Marius Renn for (OutputPort outputPort : mOutputPorts.values()) { 5118541cea20c74fdfe35a6c63c09459dd969292b7eMarius Renn if (!outputPort.isOpen()) { 5128541cea20c74fdfe35a6c63c09459dd969292b7eMarius Renn outputPort.open(); 5138541cea20c74fdfe35a6c63c09459dd969292b7eMarius Renn } 51430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 51521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 51630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 51748189dec808108f392000edbdc90bbd6b1818671Marius Renn final void clearInputs() { 51848189dec808108f392000edbdc90bbd6b1818671Marius Renn for (InputPort inputPort : mInputPorts.values()) { 51948189dec808108f392000edbdc90bbd6b1818671Marius Renn inputPort.clear(); 52048189dec808108f392000edbdc90bbd6b1818671Marius Renn } 52148189dec808108f392000edbdc90bbd6b1818671Marius Renn } 52248189dec808108f392000edbdc90bbd6b1818671Marius Renn 523489c240d3ae33e83dc62ea6f3cc864e47c0e2e3bMarius Renn final void clearOutputs() { 524489c240d3ae33e83dc62ea6f3cc864e47c0e2e3bMarius Renn for (OutputPort outputPort : mOutputPorts.values()) { 525489c240d3ae33e83dc62ea6f3cc864e47c0e2e3bMarius Renn outputPort.clear(); 526489c240d3ae33e83dc62ea6f3cc864e47c0e2e3bMarius Renn } 527489c240d3ae33e83dc62ea6f3cc864e47c0e2e3bMarius Renn } 528489c240d3ae33e83dc62ea6f3cc864e47c0e2e3bMarius Renn 52976f9fef4322f86842fda773a3753172878e311f7Marius Renn final void notifyFieldPortValueUpdated(String name, FilterContext context) { 5308541cea20c74fdfe35a6c63c09459dd969292b7eMarius Renn if (mStatus == STATUS_PROCESSING || mStatus == STATUS_PREPARED) { 53176f9fef4322f86842fda773a3753172878e311f7Marius Renn fieldPortValueUpdated(name, context); 53276f9fef4322f86842fda773a3753172878e311f7Marius Renn } 53376f9fef4322f86842fda773a3753172878e311f7Marius Renn } 53476f9fef4322f86842fda773a3753172878e311f7Marius Renn 535f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn final synchronized void pushInputFrame(String inputName, Frame frame) { 536f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn FilterPort port = getInputPort(inputName); 537f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn if (!port.isOpen()) { 538f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn port.open(); 539f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn } 540f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn port.pushFrame(frame); 541f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn } 542f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn 543f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn final synchronized void pushInputValue(String inputName, Object value) { 544f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn pushInputFrame(inputName, wrapInputValue(inputName, value)); 545f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn } 546f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn 54721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Filter internal methods ///////////////////////////////////////////////////////////////////// 54821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void initFinalPorts(KeyValueMap values) { 549f24dc0f733da39b32f15177871a79810d52e6212Marius Renn mInputPorts = new HashMap<String, InputPort>(); 550f24dc0f733da39b32f15177871a79810d52e6212Marius Renn mOutputPorts = new HashMap<String, OutputPort>(); 55121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addAndSetFinalPorts(values); 55221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 55330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 55421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void initRemainingPorts(KeyValueMap values) { 55521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addAnnotatedPorts(); 55621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn setupPorts(); // TODO: rename to addFilterPorts() ? 55721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn setInitialInputValues(values); 55830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 55930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 56021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void addAndSetFinalPorts(KeyValueMap values) { 56121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn Class filterClass = getClass(); 56221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn Annotation annotation; 56321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn for (Field field : filterClass.getDeclaredFields()) { 56421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if ((annotation = field.getAnnotation(GenerateFinalPort.class)) != null) { 56521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn GenerateFinalPort generator = (GenerateFinalPort)annotation; 56621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn String name = generator.name().isEmpty() ? field.getName() : generator.name(); 56721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn boolean hasDefault = generator.hasDefault(); 56821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addFieldPort(name, field, hasDefault, true); 56921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (values.containsKey(name)) { 57021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn setImmediateInputValue(name, values.get(name)); 57121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn values.remove(name); 57221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } else if (!generator.hasDefault()) { 57321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn throw new RuntimeException("No value specified for final input port '" 57421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn + name + "' of filter " + this + "!"); 57521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 57630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 57730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 57830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 57930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 58021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void addAnnotatedPorts() { 58121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn Class filterClass = getClass(); 58221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn Annotation annotation; 58321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn for (Field field : filterClass.getDeclaredFields()) { 58421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if ((annotation = field.getAnnotation(GenerateFieldPort.class)) != null) { 58521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn GenerateFieldPort generator = (GenerateFieldPort)annotation; 58621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addFieldGenerator(generator, field); 58721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } else if ((annotation = field.getAnnotation(GenerateProgramPort.class)) != null) { 58821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn GenerateProgramPort generator = (GenerateProgramPort)annotation; 58921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addProgramGenerator(generator, field); 59021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } else if ((annotation = field.getAnnotation(GenerateProgramPorts.class)) != null) { 59121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn GenerateProgramPorts generators = (GenerateProgramPorts)annotation; 59221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn for (GenerateProgramPort generator : generators.value()) { 59321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addProgramGenerator(generator, field); 59421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 59530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 59630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 59730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 59830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 59921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void addFieldGenerator(GenerateFieldPort generator, Field field) { 60021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn String name = generator.name().isEmpty() ? field.getName() : generator.name(); 60121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn boolean hasDefault = generator.hasDefault(); 60221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addFieldPort(name, field, hasDefault, false); 60330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 60430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 60521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void addProgramGenerator(GenerateProgramPort generator, Field field) { 60621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn String name = generator.name(); 60721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn String varName = generator.variableName().isEmpty() ? name 60821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn : generator.variableName(); 60921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn Class varType = generator.type(); 61021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn boolean hasDefault = generator.hasDefault(); 61121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addProgramPort(name, varName, field, varType, hasDefault); 61221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 61330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 61421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void setInitialInputValues(KeyValueMap values) { 61521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn for (Entry<String, Object> entry : values.entrySet()) { 61621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn setInputValue(entry.getKey(), entry.getValue()); 61730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 61821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 61930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 62021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void setImmediateInputValue(String name, Object value) { 62157774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Setting immediate value " + value + " for port " + name + "!"); 62221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn FilterPort port = getInputPort(name); 62321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn port.open(); 624bf4aaebc555cfb1e49ee411e3477203749fe6a11Marius Renn port.setFrame(SimpleFrame.wrapObject(value, null)); 62530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 62630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 62721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void transferInputFrames(FilterContext context) { 628f24dc0f733da39b32f15177871a79810d52e6212Marius Renn for (InputPort inputPort : mInputPorts.values()) { 62921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn inputPort.transfer(context); 63021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 63121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 63230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 633f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn private final Frame wrapInputValue(String inputName, Object value) { 634bf4aaebc555cfb1e49ee411e3477203749fe6a11Marius Renn MutableFrameFormat inputFormat = ObjectFormat.fromObject(value, FrameFormat.TARGET_SIMPLE); 635f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn if (value == null) { 636f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn // If the value is null, the format cannot guess the class, so we adjust it to the 637f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn // class of the input port here 638f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn FrameFormat portFormat = getInputPort(inputName).getPortFormat(); 639f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn Class portClass = (portFormat == null) ? null : portFormat.getObjectClass(); 640f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn inputFormat.setObjectClass(portClass); 641f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn } 6427eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn 6437eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn // Serialize if serializable, and type is not an immutable primitive. 6447eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn boolean shouldSerialize = !(value instanceof Number) 6457eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn && !(value instanceof Boolean) 6467eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn && !(value instanceof String) 6477eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn && value instanceof Serializable; 6487eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn 6497eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn // Create frame wrapper 6507eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn Frame frame = shouldSerialize 6517eacc1981bcbd53a79721b23a2a9da6fd0c0a1abMarius Renn ? new SerializedFrame(inputFormat, null) 652bf4aaebc555cfb1e49ee411e3477203749fe6a11Marius Renn : new SimpleFrame(inputFormat, null); 653f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn frame.setObjectValue(value); 654f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn return frame; 655f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn } 656f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn 65721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void releasePulledFrames(FilterContext context) { 65821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn for (Frame frame : mFramesToRelease) { 65921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn context.getFrameManager().releaseFrame(frame); 66021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 66121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mFramesToRelease.clear(); 66230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 66330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 66421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final boolean inputConditionsMet() { 66521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn for (FilterPort port : mInputPorts.values()) { 66621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (!port.isReady()) { 66757774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Input condition not met: " + port + "!"); 66821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return false; 66930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 67030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 67121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return true; 67230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 67330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 67421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final boolean outputConditionsMet() { 67521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn for (FilterPort port : mOutputPorts.values()) { 67621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (!port.isReady()) { 67757774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Output condition not met: " + port + "!"); 67821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return false; 67930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 68030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 68121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return true; 68230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 68330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 68421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final void closePorts() { 68557774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Closing all ports on " + this + "!"); 686f24dc0f733da39b32f15177871a79810d52e6212Marius Renn for (InputPort inputPort : mInputPorts.values()) { 68721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn inputPort.close(); 68821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 689f24dc0f733da39b32f15177871a79810d52e6212Marius Renn for (OutputPort outputPort : mOutputPorts.values()) { 69021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn outputPort.close(); 69130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 69230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 69330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 69421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private final boolean filterMustClose() { 695f24dc0f733da39b32f15177871a79810d52e6212Marius Renn for (InputPort inputPort : mInputPorts.values()) { 69621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (inputPort.filterMustClose()) { 69757774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Filter " + this + " must close due to port " + inputPort); 69821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return true; 69930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 70030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 701f24dc0f733da39b32f15177871a79810d52e6212Marius Renn for (OutputPort outputPort : mOutputPorts.values()) { 70221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn if (outputPort.filterMustClose()) { 70357774b9e8ea96fa5088e68bac7a21465fa429b15Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Filter " + this + " must close due to port " + outputPort); 70421d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return true; 70521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 70621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 70721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return false; 70830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 70930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 710