Home | History | Annotate | Download | only in filterfw
      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 
     18 package android.filterfw;
     19 
     20 import android.content.Context;
     21 import android.filterfw.core.AsyncRunner;
     22 import android.filterfw.core.FilterGraph;
     23 import android.filterfw.core.FilterContext;
     24 import android.filterfw.core.FrameManager;
     25 import android.filterfw.core.GraphRunner;
     26 import android.filterfw.core.RoundRobinScheduler;
     27 import android.filterfw.core.SyncRunner;
     28 import android.filterfw.io.GraphIOException;
     29 import android.filterfw.io.GraphReader;
     30 import android.filterfw.io.TextGraphReader;
     31 
     32 import java.util.ArrayList;
     33 
     34 /**
     35  * A GraphEnvironment provides a simple front-end to filter graph setup and execution using the
     36  * mobile filter framework. Typically, you use a GraphEnvironment in the following fashion:
     37  *   1. Instantiate a new GraphEnvironment instance.
     38  *   2. Perform any configuration, such as adding graph references and setting a GL environment.
     39  *   3. Load a graph file using loadGraph() or add a graph using addGraph().
     40  *   4. Obtain a GraphRunner instance using getRunner().
     41  *   5. Execute the obtained runner.
     42  * Note that it is possible to add multiple graphs and runners to a single GraphEnvironment.
     43  *
     44  * @hide
     45  */
     46 public class GraphEnvironment extends MffEnvironment {
     47 
     48     public static final int MODE_ASYNCHRONOUS = 1;
     49     public static final int MODE_SYNCHRONOUS  = 2;
     50 
     51     private GraphReader mGraphReader;
     52     private ArrayList<GraphHandle> mGraphs = new ArrayList<GraphHandle>();
     53 
     54     private class GraphHandle {
     55         private FilterGraph mGraph;
     56         private AsyncRunner mAsyncRunner;
     57         private SyncRunner mSyncRunner;
     58 
     59         public GraphHandle(FilterGraph graph) {
     60             mGraph = graph;
     61         }
     62 
     63         public FilterGraph getGraph() {
     64             return mGraph;
     65         }
     66 
     67         public AsyncRunner getAsyncRunner(FilterContext environment) {
     68             if (mAsyncRunner == null) {
     69                 mAsyncRunner = new AsyncRunner(environment, RoundRobinScheduler.class);
     70                 mAsyncRunner.setGraph(mGraph);
     71             }
     72             return mAsyncRunner;
     73         }
     74 
     75         public GraphRunner getSyncRunner(FilterContext environment) {
     76             if (mSyncRunner == null) {
     77                 mSyncRunner = new SyncRunner(environment, mGraph, RoundRobinScheduler.class);
     78             }
     79             return mSyncRunner;
     80         }
     81     }
     82 
     83     /**
     84      * Create a new GraphEnvironment with default components.
     85      */
     86     public GraphEnvironment() {
     87         super(null);
     88     }
     89 
     90     /**
     91      * Create a new GraphEnvironment with a custom FrameManager and GraphReader. Specifying null
     92      * for either of these, will auto-create a default instance.
     93      *
     94      * @param frameManager The FrameManager to use, or null to auto-create one.
     95      * @param reader        The GraphReader to use for graph loading, or null to auto-create one.
     96      *                      Note, that the reader will not be created until it is required. Pass
     97      *                      null if you will not load any graph files.
     98      */
     99     public GraphEnvironment(FrameManager frameManager, GraphReader reader) {
    100         super(frameManager);
    101         mGraphReader = reader;
    102     }
    103 
    104     /**
    105      * Returns the used graph reader. This will create one, if a reader has not been set already.
    106      */
    107     public GraphReader getGraphReader() {
    108         if (mGraphReader == null) {
    109             mGraphReader = new TextGraphReader();
    110         }
    111         return mGraphReader;
    112     }
    113 
    114     /**
    115      * Add graph references to resolve during graph reading. The references added here are shared
    116      * among all graphs.
    117      *
    118      * @param references An alternating argument list of keys (Strings) and values.
    119      */
    120     public void addReferences(Object... references) {
    121         getGraphReader().addReferencesByKeysAndValues(references);
    122     }
    123 
    124     /**
    125      * Loads a graph file from the specified resource and adds it to this environment.
    126      *
    127      * @param context       The context in which to read the resource.
    128      * @param resourceId    The ID of the graph resource to load.
    129      * @return              A unique ID for the graph.
    130      */
    131     public int loadGraph(Context context, int resourceId) {
    132         // Read the file into a graph
    133         FilterGraph graph = null;
    134         try {
    135             graph = getGraphReader().readGraphResource(context, resourceId);
    136         } catch (GraphIOException e) {
    137             throw new RuntimeException("Could not read graph: " + e.getMessage());
    138         }
    139 
    140         // Add graph to our list of graphs
    141         return addGraph(graph);
    142     }
    143 
    144     /**
    145      * Add a graph to the environment. Consider using loadGraph() if you are loading a graph from
    146      * a graph file.
    147      *
    148      * @param graph The graph to add to the environment.
    149      * @return      A unique ID for the added graph.
    150      */
    151     public int addGraph(FilterGraph graph) {
    152         GraphHandle graphHandle = new GraphHandle(graph);
    153         mGraphs.add(graphHandle);
    154         return mGraphs.size() - 1;
    155     }
    156 
    157     /**
    158      * Access a specific graph of this environment given a graph ID (previously returned from
    159      * loadGraph() or addGraph()). Throws an InvalidArgumentException if no graph with the
    160      * specified ID could be found.
    161      *
    162      * @param graphId   The ID of the graph to get.
    163      * @return          The graph with the specified ID.
    164      */
    165     public FilterGraph getGraph(int graphId) {
    166         if (graphId < 0 || graphId >= mGraphs.size()) {
    167             throw new IllegalArgumentException(
    168                 "Invalid graph ID " + graphId + " specified in runGraph()!");
    169         }
    170         return mGraphs.get(graphId).getGraph();
    171     }
    172 
    173     /**
    174      * Get a GraphRunner instance for the graph with the specified ID. The GraphRunner instance can
    175      * be used to execute the graph. Throws an InvalidArgumentException if no graph with the
    176      * specified ID could be found.
    177      *
    178      * @param graphId       The ID of the graph to get.
    179      * @param executionMode The mode of graph execution. Currently this can be either
    180                             MODE_SYNCHRONOUS or MODE_ASYNCHRONOUS.
    181      * @return              A GraphRunner instance for this graph.
    182      */
    183     public GraphRunner getRunner(int graphId, int executionMode) {
    184         switch (executionMode) {
    185             case MODE_ASYNCHRONOUS:
    186                 return mGraphs.get(graphId).getAsyncRunner(getContext());
    187 
    188             case MODE_SYNCHRONOUS:
    189                 return mGraphs.get(graphId).getSyncRunner(getContext());
    190 
    191             default:
    192                 throw new RuntimeException(
    193                     "Invalid execution mode " + executionMode + " specified in getRunner()!");
    194         }
    195     }
    196 
    197 }
    198