1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18package android.filterfw.core;
19
20import java.util.Map.Entry;
21
22/**
23 * @hide
24 */
25public class FilterFunction {
26
27    private Filter mFilter;
28    private FilterContext mFilterContext;
29    private boolean mFilterIsSetup = false;
30    private FrameHolderPort[] mResultHolders;
31
32    private class FrameHolderPort extends StreamPort {
33        public FrameHolderPort() {
34            super(null, "holder");
35        }
36    }
37
38    public FilterFunction(FilterContext context, Filter filter) {
39        mFilterContext = context;
40        mFilter = filter;
41    }
42
43    public Frame execute(KeyValueMap inputMap) {
44        int filterOutCount = mFilter.getNumberOfOutputs();
45
46        // Sanity checks
47        if (filterOutCount > 1) {
48            throw new RuntimeException("Calling execute on filter " + mFilter + " with multiple "
49                + "outputs! Use executeMulti() instead!");
50        }
51
52        // Setup filter
53        if (!mFilterIsSetup) {
54            connectFilterOutputs();
55            mFilterIsSetup = true;
56        }
57
58        // Make sure GL environment is active
59        boolean didActivateGLEnv = false;
60        GLEnvironment glEnv = mFilterContext.getGLEnvironment();
61        if (glEnv != null && !glEnv.isActive()) {
62            glEnv.activate();
63            didActivateGLEnv = true;
64        }
65
66        // Setup the inputs
67        for (Entry<String, Object> entry : inputMap.entrySet()) {
68            if (entry.getValue() instanceof Frame) {
69                mFilter.pushInputFrame(entry.getKey(), (Frame)entry.getValue());
70            } else {
71                mFilter.pushInputValue(entry.getKey(), entry.getValue());
72            }
73        }
74
75        // Process the filter
76        if (mFilter.getStatus() != Filter.STATUS_PROCESSING) {
77            mFilter.openOutputs();
78        }
79
80        mFilter.performProcess(mFilterContext);
81
82        // Create result handle
83        Frame result = null;
84        if (filterOutCount == 1 && mResultHolders[0].hasFrame()) {
85            result = mResultHolders[0].pullFrame();
86        }
87
88        // Deactivate GL environment if activated
89        if (didActivateGLEnv) {
90            glEnv.deactivate();
91        }
92
93        return result;
94    }
95
96    public Frame executeWithArgList(Object... inputs) {
97        return execute(KeyValueMap.fromKeyValues(inputs));
98    }
99
100    public void close() {
101        mFilter.performClose(mFilterContext);
102    }
103
104    public FilterContext getContext() {
105        return mFilterContext;
106    }
107
108    public Filter getFilter() {
109        return mFilter;
110    }
111
112    public void setInputFrame(String input, Frame frame) {
113        mFilter.setInputFrame(input, frame);
114    }
115
116    public void setInputValue(String input, Object value) {
117        mFilter.setInputValue(input, value);
118    }
119
120    public void tearDown() {
121        mFilter.performTearDown(mFilterContext);
122        mFilter = null;
123    }
124
125    @Override
126    public String toString() {
127        return mFilter.getName();
128    }
129
130    private void connectFilterOutputs() {
131        int  i = 0;
132        mResultHolders = new FrameHolderPort[mFilter.getNumberOfOutputs()];
133        for (OutputPort outputPort : mFilter.getOutputPorts()) {
134            mResultHolders[i] = new FrameHolderPort();
135            outputPort.connectTo(mResultHolders[i]);
136            ++i;
137        }
138    }
139}
140