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*> ¶ms,
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