1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package androidx.media.filterfw;
16 
17 import java.util.Vector;
18 
19 class FrameQueue {
20 
21     public static class Builder {
22 
23         private FrameType mReadType = null;
24         private FrameType mWriteType = null;
25 
26         private Vector<FrameQueue> mAttachedQueues = new Vector<FrameQueue>();
27 
Builder()28         public Builder() {}
29 
setWriteType(FrameType type)30         public void setWriteType(FrameType type) {
31             mWriteType = type;
32         }
33 
setReadType(FrameType type)34         public void setReadType(FrameType type) {
35             mReadType = type;
36         }
37 
attachQueue(FrameQueue queue)38         public void attachQueue(FrameQueue queue) {
39             mAttachedQueues.add(queue);
40         }
41 
build(String name)42         public FrameQueue build(String name) {
43             FrameType type = buildType();
44             // TODO: This currently does not work correctly (Try camera -> branch -> target-slot)
45             //validateType(type, name);
46             FrameQueue result = new FrameQueue(type, name);
47             buildQueueImpl(result);
48             return result;
49         }
50 
buildQueueImpl(FrameQueue queue)51         private void buildQueueImpl(FrameQueue queue) {
52             QueueImpl queueImpl = queue.new SingleFrameQueueImpl();
53             queue.mQueueImpl = queueImpl;
54         }
55 
buildType()56         private FrameType buildType() {
57             FrameType result = FrameType.merge(mWriteType, mReadType);
58             for (FrameQueue queue : mAttachedQueues) {
59                 result = FrameType.merge(result, queue.mType);
60             }
61             return result;
62         }
63 
64         /*
65         private void validateType(FrameType type, String queueName) {
66             if (!type.isSpecified()) {
67                 throw new RuntimeException("Cannot build connection queue '" + queueName + "' as "
68                         + "its type (" + type + ") is underspecified!");
69             }
70         }
71          */
72     }
73 
74     private interface QueueImpl {
canPull()75         public boolean canPull();
76 
canPush()77         public boolean canPush();
78 
pullFrame()79         public Frame pullFrame();
80 
fetchAvailableFrame(int[] dimensions)81         public Frame fetchAvailableFrame(int[] dimensions);
82 
peek()83         public Frame peek();
84 
pushFrame(Frame frame)85         public void pushFrame(Frame frame);
86 
clear()87         public void clear();
88     }
89 
90     private class SingleFrameQueueImpl implements QueueImpl {
91         private Frame mFrame = null;
92 
93         @Override
canPull()94         public boolean canPull() {
95             return mFrame != null;
96         }
97 
98         @Override
canPush()99         public boolean canPush() {
100             return mFrame == null;
101         }
102 
103         @Override
pullFrame()104         public Frame pullFrame() {
105             Frame result = mFrame;
106             mFrame = null;
107             return result;
108         }
109 
110         @Override
peek()111         public Frame peek() {
112             return mFrame;
113         }
114 
115         @Override
fetchAvailableFrame(int[] dimensions)116         public Frame fetchAvailableFrame(int[] dimensions) {
117             // Note that we cannot use a cached frame here, as we do not know where that cached
118             // instance would end up.
119             FrameManager manager = FrameManager.current();
120             return new Frame(mType, dimensions, manager);
121         }
122 
123         @Override
pushFrame(Frame frame)124         public void pushFrame(Frame frame) {
125             mFrame = frame.retain();
126             mFrame.setReadOnly(true);
127         }
128 
129         @Override
clear()130         public void clear() {
131             if (mFrame != null) {
132                 mFrame.release();
133                 mFrame = null;
134             }
135         }
136     }
137 
138     private QueueImpl mQueueImpl;
139     private FrameType mType;
140     private String mName;
141 
getType()142     public FrameType getType() {
143         return mType;
144     }
145 
canPull()146     public boolean canPull() {
147         return mQueueImpl.canPull();
148     }
149 
canPush()150     public boolean canPush() {
151         return mQueueImpl.canPush();
152     }
153 
pullFrame()154     public Frame pullFrame() {
155         return mQueueImpl.pullFrame();
156     }
157 
fetchAvailableFrame(int[] dimensions)158     public Frame fetchAvailableFrame(int[] dimensions) {
159         return mQueueImpl.fetchAvailableFrame(dimensions);
160     }
161 
pushFrame(Frame frame)162     public void pushFrame(Frame frame) {
163         mQueueImpl.pushFrame(frame);
164     }
165 
peek()166     public Frame peek() {
167         return mQueueImpl.peek();
168     }
169 
170     @Override
toString()171     public String toString() {
172         return mName;
173     }
174 
clear()175     public void clear() {
176         mQueueImpl.clear();
177     }
178 
FrameQueue(FrameType type, String name)179     private FrameQueue(FrameType type, String name) {
180         mType = type;
181         mName = name;
182     }
183 
184 }
185