1 /*
2  * Copyright (C) 2018 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "Codec2-InputSurface"
19 #include <log/log.h>
20 
21 #include <codec2/hidl/1.0/InputSurface.h>
22 #include <codec2/hidl/1.0/InputSurfaceConnection.h>
23 
24 #include <util/C2InterfaceHelper.h>
25 #include <C2Component.h>
26 #include <C2Config.h>
27 
28 #include <memory>
29 
30 namespace hardware {
31 namespace google {
32 namespace media {
33 namespace c2 {
34 namespace V1_0 {
35 namespace utils {
36 
37 using namespace ::android;
38 
39 class InputSurface::ConfigurableImpl : public C2InterfaceHelper {
40 public:
ConfigurableImpl(const std::shared_ptr<C2ReflectorHelper> & helper)41     explicit ConfigurableImpl(
42             const std::shared_ptr<C2ReflectorHelper> &helper)
43         : C2InterfaceHelper(helper) {
44 
45         setDerivedInstance(this);
46 
47         addParameter(
48                 DefineParam(mEos, C2_NAME_INPUT_SURFACE_EOS_TUNING)
49                 .withDefault(new C2InputSurfaceEosTuning(false))
50                 .withFields({C2F(mEos, value).oneOf({true, false})})
51                 .withSetter(EosSetter)
52                 .build());
53     }
54 
EosSetter(bool mayBlock,C2P<C2InputSurfaceEosTuning> & me)55     static C2R EosSetter(bool mayBlock, C2P<C2InputSurfaceEosTuning> &me) {
56         (void)mayBlock;
57         return me.F(me.v.value).validatePossible(me.v.value);
58     }
59 
eos() const60     bool eos() const { return mEos->value; }
61 
62 private:
63     std::shared_ptr<C2InputSurfaceEosTuning> mEos;
64 };
65 
66 namespace {
67 
68 class ConfigurableWrapper : public ConfigurableC2Intf {
69 public:
ConfigurableWrapper(const std::shared_ptr<InputSurface::ConfigurableImpl> & impl,const sp<GraphicBufferSource> & source)70     ConfigurableWrapper(
71             const std::shared_ptr<InputSurface::ConfigurableImpl> &impl,
72             const sp<GraphicBufferSource> &source)
73         : ConfigurableC2Intf("input-surface"),
74           mImpl(impl),
75           mSource(source) {
76     }
77 
78     ~ConfigurableWrapper() override = default;
79 
query(const std::vector<C2Param::Index> & indices,c2_blocking_t mayBlock,std::vector<std::unique_ptr<C2Param>> * const params) const80     c2_status_t query(
81             const std::vector<C2Param::Index> &indices,
82             c2_blocking_t mayBlock,
83             std::vector<std::unique_ptr<C2Param>>* const params) const override {
84         return mImpl->query({}, indices, mayBlock, params);
85     }
86 
config(const std::vector<C2Param * > & params,c2_blocking_t mayBlock,std::vector<std::unique_ptr<C2SettingResult>> * const failures)87     c2_status_t config(
88             const std::vector<C2Param*> &params,
89             c2_blocking_t mayBlock,
90             std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
91         c2_status_t err = mImpl->config(params, mayBlock, failures);
92         if (mImpl->eos()) {
93             sp<GraphicBufferSource> source = mSource.promote();
94             if (source == nullptr || source->signalEndOfInputStream() != OK) {
95                 // TODO: put something in |failures|
96                 err = C2_BAD_VALUE;
97             }
98             // TODO: reset eos?
99         }
100         return err;
101     }
102 
querySupportedParams(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const103     c2_status_t querySupportedParams(
104             std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const override {
105         return mImpl->querySupportedParams(params);
106     }
107 
querySupportedValues(std::vector<C2FieldSupportedValuesQuery> & fields,c2_blocking_t mayBlock) const108     c2_status_t querySupportedValues(
109             std::vector<C2FieldSupportedValuesQuery>& fields,
110             c2_blocking_t mayBlock) const override {
111         return mImpl->querySupportedValues(fields, mayBlock);
112     }
113 
114 private:
115     const std::shared_ptr<InputSurface::ConfigurableImpl> mImpl;
116     wp<GraphicBufferSource> mSource;
117 };
118 
119 }  // namespace
120 
121 
connectToComponent(const sp<IComponent> & component,connectToComponent_cb _hidl_cb)122 Return<void> InputSurface::connectToComponent(
123         const sp<IComponent>& component,
124         connectToComponent_cb _hidl_cb) {
125     Status status;
126     sp<InputSurfaceConnection> conn;
127     if (!component) {
128         status = Status::BAD_VALUE;
129     } else {
130         std::shared_ptr<C2Component> comp = mStore->findC2Component(component);
131         if (!comp) {
132             conn = new InputSurfaceConnection(mSource, component);
133         } else {
134             conn = new InputSurfaceConnection(mSource, comp);
135         }
136         if (!conn->init()) {
137             conn = nullptr;
138             status = Status::BAD_VALUE;
139         } else {
140             status = Status::OK;
141         }
142     }
143     _hidl_cb(status, conn);
144     return Void();
145 }
146 
getConfigurable()147 Return<sp<IConfigurable>> InputSurface::getConfigurable() {
148     return mConfigurable;
149 }
150 
151 // Derived methods from IGraphicBufferProducer
152 
requestBuffer(int32_t slot,requestBuffer_cb _hidl_cb)153 Return<void> InputSurface::requestBuffer(
154         int32_t slot,
155         requestBuffer_cb _hidl_cb) {
156     return mBase->requestBuffer(slot, _hidl_cb);
157 }
158 
setMaxDequeuedBufferCount(int32_t maxDequeuedBuffers)159 Return<int32_t> InputSurface::setMaxDequeuedBufferCount(
160         int32_t maxDequeuedBuffers) {
161     return mBase->setMaxDequeuedBufferCount(maxDequeuedBuffers);
162 }
163 
setAsyncMode(bool async)164 Return<int32_t> InputSurface::setAsyncMode(
165         bool async) {
166     return mBase->setAsyncMode(async);
167 }
168 
dequeueBuffer(uint32_t width,uint32_t height,PixelFormat format,uint32_t usage,bool getFrameTimestamps,dequeueBuffer_cb _hidl_cb)169 Return<void> InputSurface::dequeueBuffer(
170         uint32_t width,
171         uint32_t height,
172         PixelFormat format,
173         uint32_t usage,
174         bool getFrameTimestamps,
175         dequeueBuffer_cb _hidl_cb) {
176     return mBase->dequeueBuffer(
177             width, height, format, usage, getFrameTimestamps, _hidl_cb);
178 }
179 
detachBuffer(int32_t slot)180 Return<int32_t> InputSurface::detachBuffer(
181         int32_t slot) {
182     return mBase->detachBuffer(slot);
183 }
184 
detachNextBuffer(detachNextBuffer_cb _hidl_cb)185 Return<void> InputSurface::detachNextBuffer(
186         detachNextBuffer_cb _hidl_cb) {
187     return mBase->detachNextBuffer(_hidl_cb);
188 }
189 
attachBuffer(const AnwBuffer & buffer,attachBuffer_cb _hidl_cb)190 Return<void> InputSurface::attachBuffer(
191         const AnwBuffer& buffer,
192         attachBuffer_cb _hidl_cb) {
193     return mBase->attachBuffer(buffer, _hidl_cb);
194 }
195 
queueBuffer(int32_t slot,const QueueBufferInput & input,queueBuffer_cb _hidl_cb)196 Return<void> InputSurface::queueBuffer(
197         int32_t slot,
198         const QueueBufferInput& input,
199         queueBuffer_cb _hidl_cb) {
200     return mBase->queueBuffer(slot, input, _hidl_cb);
201 }
202 
cancelBuffer(int32_t slot,const hidl_handle & fence)203 Return<int32_t> InputSurface::cancelBuffer(
204         int32_t slot,
205         const hidl_handle& fence) {
206     return mBase->cancelBuffer(slot, fence);
207 }
208 
query(int32_t what,query_cb _hidl_cb)209 Return<void> InputSurface::query(
210         int32_t what,
211         query_cb _hidl_cb) {
212     return mBase->query(what, _hidl_cb);
213 }
214 
connect(const sp<HProducerListener> & listener,int32_t api,bool producerControlledByApp,connect_cb _hidl_cb)215 Return<void> InputSurface::connect(
216         const sp<HProducerListener>& listener,
217         int32_t api,
218         bool producerControlledByApp,
219         connect_cb _hidl_cb) {
220     return mBase->connect(listener, api, producerControlledByApp, _hidl_cb);
221 }
222 
disconnect(int32_t api,DisconnectMode mode)223 Return<int32_t> InputSurface::disconnect(
224         int32_t api,
225         DisconnectMode mode) {
226     return mBase->disconnect(api, mode);
227 }
228 
setSidebandStream(const hidl_handle & stream)229 Return<int32_t> InputSurface::setSidebandStream(
230         const hidl_handle& stream) {
231     return mBase->setSidebandStream(stream);
232 }
233 
allocateBuffers(uint32_t width,uint32_t height,PixelFormat format,uint32_t usage)234 Return<void> InputSurface::allocateBuffers(
235         uint32_t width,
236         uint32_t height,
237         PixelFormat format,
238         uint32_t usage) {
239     return mBase->allocateBuffers(width, height, format, usage);
240 }
241 
allowAllocation(bool allow)242 Return<int32_t> InputSurface::allowAllocation(
243         bool allow) {
244     return mBase->allowAllocation(allow);
245 }
246 
setGenerationNumber(uint32_t generationNumber)247 Return<int32_t> InputSurface::setGenerationNumber(
248         uint32_t generationNumber) {
249     return mBase->setGenerationNumber(generationNumber);
250 }
251 
getConsumerName(getConsumerName_cb _hidl_cb)252 Return<void> InputSurface::getConsumerName(
253         getConsumerName_cb _hidl_cb) {
254     return mBase->getConsumerName(_hidl_cb);
255 }
256 
setSharedBufferMode(bool sharedBufferMode)257 Return<int32_t> InputSurface::setSharedBufferMode(
258         bool sharedBufferMode) {
259     return mBase->setSharedBufferMode(sharedBufferMode);
260 }
261 
setAutoRefresh(bool autoRefresh)262 Return<int32_t> InputSurface::setAutoRefresh(
263         bool autoRefresh) {
264     return mBase->setAutoRefresh(autoRefresh);
265 }
266 
setDequeueTimeout(int64_t timeoutNs)267 Return<int32_t> InputSurface::setDequeueTimeout(
268         int64_t timeoutNs) {
269     return mBase->setDequeueTimeout(timeoutNs);
270 }
271 
getLastQueuedBuffer(getLastQueuedBuffer_cb _hidl_cb)272 Return<void> InputSurface::getLastQueuedBuffer(
273         getLastQueuedBuffer_cb _hidl_cb) {
274     return mBase->getLastQueuedBuffer(_hidl_cb);
275 }
276 
getFrameTimestamps(getFrameTimestamps_cb _hidl_cb)277 Return<void> InputSurface::getFrameTimestamps(
278         getFrameTimestamps_cb _hidl_cb) {
279     return mBase->getFrameTimestamps(_hidl_cb);
280 }
281 
getUniqueId(getUniqueId_cb _hidl_cb)282 Return<void> InputSurface::getUniqueId(
283         getUniqueId_cb _hidl_cb) {
284     return mBase->getUniqueId(_hidl_cb);
285 }
286 
287 // Constructor is exclusive to ComponentStore.
InputSurface(const sp<ComponentStore> & store,const std::shared_ptr<C2ReflectorHelper> & reflector,const sp<HGraphicBufferProducer> & base,const sp<GraphicBufferSource> & source)288 InputSurface::InputSurface(
289         const sp<ComponentStore>& store,
290         const std::shared_ptr<C2ReflectorHelper>& reflector,
291         const sp<HGraphicBufferProducer>& base,
292         const sp<GraphicBufferSource>& source) :
293     mStore(store),
294     mBase(base),
295     mSource(source),
296     mHelper(std::make_shared<ConfigurableImpl>(reflector)),
297     mConfigurable(new CachedConfigurable(
298             std::make_unique<ConfigurableWrapper>(mHelper, source))) {
299 
300     mConfigurable->init(store.get());
301 }
302 
303 }  // namespace utils
304 }  // namespace V1_0
305 }  // namespace c2
306 }  // namespace media
307 }  // namespace google
308 }  // namespace hardware
309 
310