1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/* 2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright (C) 2011 The Android Open Source Project 3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License"); 5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License. 6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at 7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * http://www.apache.org/licenses/LICENSE-2.0 9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software 11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS, 12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and 14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License. 15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspackage androidx.media.filterfw; 18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/** 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Output ports are the data emitting ports of filters. 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <p> 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Filters push data frames onto output-ports, which in turn push them onto their connected input 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * ports. Output ports must be connected to an input port before data can be pushed onto them. 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Input and output ports share their Frame slot, meaning that when a frame is waiting on an output 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * port, it is also waiting on the connected input port. 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * </p><p> 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Only one frame can be pushed onto an output port at a time. In other words, a Frame must first 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * be consumed by the target filter before a new frame can be pushed on the output port. If the 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * output port is set to wait until it becomes free (see {@link #setWaitsUntilAvailable(boolean)}), 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * it is guaranteed to be available when {@code onProcess()} is called. This is the default setting. 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * </p> 32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic final class OutputPort { 34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Filter mFilter; 36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private String mName; 37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Signature.PortInfo mInfo; 38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private FrameQueue.Builder mQueueBuilder = null; 39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private FrameQueue mQueue = null; 40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mWaitsUntilAvailable = true; 41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private InputPort mTarget = null; 42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns true, if this port is connected to a target port. 45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if this port is connected to a target port. 46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean isConnected() { 48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mTarget != null; 49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns true, if there is no frame waiting on this port. 53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if no Frame instance is waiting on this port. 54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean isAvailable() { 56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mQueue == null || mQueue.canPush(); 57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns a frame for writing. 61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Call this method to fetch a new frame to write into. When you have finished writing the 63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * frame data, you can push it into the output queue using {@link #pushFrame(Frame)}. Note, 64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * that the Frame returned is owned by the queue. If you wish to hold on to the frame, you 65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * must detach it. 66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param dimensions the size of the Frame you wish to obtain. 68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return a writable Frame instance. 69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public Frame fetchAvailableFrame(int[] dimensions) { 71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Frame frame = getQueue().fetchAvailableFrame(dimensions); 72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (frame != null) { 73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks //Log.i("OutputPort", "Adding frame " + frame + " to auto-release pool"); 74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilter.addAutoReleaseFrame(frame); 75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return frame; 77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Pushes a frame onto this output port. 81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is typically a Frame instance you obtained by previously calling 83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #fetchAvailableFrame(int[])}, but may come from other sources such as an input port 84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * that is attached to this output port. 85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Once you have pushed a frame to an output, you may no longer modify it as it may be shared 87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * among other filters. 88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param frame the frame to push to the output queue. 90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void pushFrame(Frame frame) { 92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Some queues allow pushing without fetching, so we need to make sure queue is open 93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // before pushing! 94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks long timestamp = frame.getTimestamp(); 95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (timestamp == Frame.TIMESTAMP_NOT_SET) 96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks frame.setTimestamp(mFilter.getCurrentTimestamp()); 97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks getQueue().pushFrame(frame); 98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Sets whether to wait until this port becomes available before processing. 102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * When set to true, the Filter will not be scheduled for processing unless there is no Frame 103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * waiting on this port. The default value is true. 104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param wait true, if filter should wait for the port to become available before processing. 106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #waitsUntilAvailable() 107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void setWaitsUntilAvailable(boolean wait) { 109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mWaitsUntilAvailable = wait; 110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns whether the filter waits until this port is available before processing. 114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return true, if the filter waits until this port is available before processing. 115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see #setWaitsUntilAvailable(boolean) 116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean waitsUntilAvailable() { 118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mWaitsUntilAvailable; 119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the output port's name. 123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * This is the name that was specified when the output port was connected. 124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the output port's name. 126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public String getName() { 128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mName; 129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Return the filter object that this port belongs to. 133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the output port's filter. 135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public Filter getFilter() { 137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mFilter; 138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public String toString() { 142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mFilter.getName() + ":" + mName; 143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks OutputPort(Filter filter, String name, Signature.PortInfo info) { 146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilter = filter; 147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mName = name; 148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mInfo = info; 149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void setTarget(InputPort target) { 152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mTarget = target; 153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Return the (input) port that this output port is connected to. 157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the connected port, null if not connected. 159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public InputPort getTarget() { 161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mTarget; 162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameQueue getQueue() { 165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mQueue; 166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void setQueue(FrameQueue queue) { 169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueue = queue; 170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueueBuilder = null; 171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 173227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void onOpen(FrameQueue.Builder builder) { 174227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueueBuilder = builder; 175227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueueBuilder.setWriteType(mInfo.type); 176227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFilter.onOutputPortOpen(this); 177227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 178227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 179227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks boolean isOpen() { 180227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mQueue != null; 181227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 182227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 183227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final boolean conditionsMet() { 184227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return !mWaitsUntilAvailable || isAvailable(); 185227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 186227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 187227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void clear() { 188227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mQueue != null) { 189227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mQueue.clear(); 190227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 191227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 192227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks} 193227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 194