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 Hendricksimport java.util.Arrays; 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/** 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Frames are the data containers that are transported between Filters. 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Frames may be used only within a Filter during filter graph execution. Accessing Frames outside 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * of graph execution may cause unexpected results. 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * There are two ways to obtain new Frame instances. You can call 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link OutputPort#fetchAvailableFrame(int[])} on an OutputPort to obtain a Frame to pass to an 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * output. You can also call {@link #create(FrameType, int[])} to obtain 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * a detached Frame instance that you may hold onto in your filter. If you need to hold on to a 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Frame that is owned by an input or output queue, you must call 32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #retain()} on it. 33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * When you are done using a detached Frame, you must release it yourself. 35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * To access frame data, call any of the {@code lock}-methods. This will give you access to the 37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * frame data in the desired format. You must pass in a {@code mode} indicating whether you wish 38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * to read or write to the data. Writing to a read-locked Frame may produce unexpected results and 39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * interfere with other filters. When you are done reading or writing to the data, you must call 40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #unlock()}. Note, that a Frame must be unlocked before you push it into an output queue. 41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Generally, any type of access format to a Frame's data will be granted. However, it is strongly 43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * recommended to specify the access format that you intend to use in your filter's signature or 44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * in the access flags passed to {@code newFrame()}. This will allow the Frame to allocate 45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * the most efficient backings for the intended type of access. 46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * A frame can be be pushed to an OutputPort by calling the {@link OutputPort#pushFrame(Frame)} 48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * method. Frames that have been pushed become read-only, and can no longer be modified. 49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * On the other end, a Filter can pull in an input Frame by calling {@link InputPort#pullFrame()} 51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * on the desired InputPort. Such frames are always read-only. 52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic class Frame { 54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** Special timestamp value indicating that no time-stamp was set. */ 56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static final long TIMESTAMP_NOT_SET = -1; 57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** Frame data access mode: Read */ 59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static final int MODE_READ = 1; 60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** Frame data access mode: Write */ 61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static final int MODE_WRITE = 2; 62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks BackingStore mBackingStore; 64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks boolean mReadOnly = false; 65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Public API ////////////////////////////////////////////////////////////////////////////////// 67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns the frame's type. 69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return A FrameType instance describing the frame data-type. 70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final FrameType getType() { 72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mBackingStore.getFrameType(); 73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final int getElementCount() { 76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mBackingStore.getElementCount(); 77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Set the frame's timestamp in nanoseconds. 81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @param timestamp the timestamp of this frame in nanoseconds. 83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final void setTimestamp(long timestamp) { 85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mBackingStore.setTimestamp(timestamp); 86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the frame's timestamp in nanoseconds. 90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final long getTimestamp() { 92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mBackingStore.getTimestamp(); 93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @return the frame's timestamp in milliseconds. 97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final long getTimestampMillis() { 99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mBackingStore.getTimestamp() / 1000000L; 100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final boolean isReadOnly() { 103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mReadOnly; 104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final FrameValue asFrameValue() { 107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return FrameValue.create(mBackingStore); 108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final FrameValues asFrameValues() { 111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return FrameValues.create(mBackingStore); 112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final FrameBuffer1D asFrameBuffer1D() { 115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return FrameBuffer1D.create(mBackingStore); 116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final FrameBuffer2D asFrameBuffer2D() { 119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return FrameBuffer2D.create(mBackingStore); 120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final FrameImage2D asFrameImage2D() { 123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return FrameImage2D.create(mBackingStore); 124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public String toString() { 128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return "Frame[" + getType().toString() + "]: " + mBackingStore; 129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public boolean equals(Object object) { 133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return object instanceof Frame && ((Frame)object).mBackingStore == mBackingStore; 134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static Frame create(FrameType type, int[] dimensions) { 137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameManager manager = FrameManager.current(); 138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (manager == null) { 139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IllegalStateException("Attempting to create new Frame outside of " 140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "FrameManager context!"); 141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return new Frame(type, dimensions, manager); 143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final Frame release() { 146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mBackingStore = mBackingStore.release(); 147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mBackingStore != null ? this : null; 148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public final Frame retain() { 151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mBackingStore = mBackingStore.retain(); 152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return this; 153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void unlock() { 156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!mBackingStore.unlock()) { 157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Attempting to unlock frame that is not locked!"); 158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public int[] getDimensions() { 162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int[] dim = mBackingStore.getDimensions(); 163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return dim != null ? Arrays.copyOf(dim, dim.length) : null; 164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Frame(FrameType type, int[] dimensions, FrameManager manager) { 167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mBackingStore = new BackingStore(type, dimensions, manager); 168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Frame(BackingStore backingStore) { 171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mBackingStore = backingStore; 172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 173227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 174227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void assertAccessible(int mode) { 175227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Make sure frame is in write-mode 176227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mReadOnly && mode == MODE_WRITE) { 177227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Attempting to write to read-only frame " + this + "!"); 178227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 179227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 180227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 181227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks final void setReadOnly(boolean readOnly) { 182227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mReadOnly = readOnly; 183227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 184227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 185227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void resize(int[] newDims) { 186227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int[] oldDims = mBackingStore.getDimensions(); 187227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int oldCount = oldDims == null ? 0 : oldDims.length; 188227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int newCount = newDims == null ? 0 : newDims.length; 189227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (oldCount != newCount) { 190227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IllegalArgumentException("Cannot resize " + oldCount + "-dimensional " 191227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + "Frame to " + newCount + "-dimensional Frame!"); 192227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (newDims != null && !Arrays.equals(oldDims, newDims)) { 193227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mBackingStore.resize(newDims); 194227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 195227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 196227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 197227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Frame makeCpuCopy(FrameManager frameManager) { 198227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Frame frame = new Frame(getType(), getDimensions(), frameManager); 199227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks frame.mBackingStore.importStore(mBackingStore); 200227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return frame; 201227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 202227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks} 203227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 204