1 /*
2  * Copyright 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 #ifndef CODEC2_HIDL_CLIENT_H
18 #define CODEC2_HIDL_CLIENT_H
19 
20 #include <C2PlatformSupport.h>
21 #include <C2Component.h>
22 #include <C2Buffer.h>
23 #include <C2Param.h>
24 #include <C2.h>
25 
26 #include <gui/IGraphicBufferProducer.h>
27 #include <hidl/HidlSupport.h>
28 #include <utils/StrongPointer.h>
29 
30 #include <functional>
31 #include <map>
32 #include <memory>
33 #include <mutex>
34 
35 /**
36  * This file contains minimal interfaces for the framework to access Codec2.0.
37  *
38  * Codec2Client is the main class that contains the following inner classes:
39  * - Listener
40  * - Configurable
41  * - Interface
42  * - Component
43  *
44  * Classes in Codec2Client, interfaces in Codec2.0, and  HIDL interfaces are
45  * related as follows:
46  * - Codec2Client <==> C2ComponentStore <==> IComponentStore
47  * - Codec2Client::Listener <==> C2Component::Listener <==> IComponentListener
48  * - Codec2Client::Configurable <==> [No equivalent] <==> IConfigurable
49  * - Codec2Client::Interface <==> C2ComponentInterface <==> IComponentInterface
50  * - Codec2Client::Component <==> C2Component <==> IComponent
51  *
52  * The entry point is Codec2Client::CreateFromService(), which creates a
53  * Codec2Client object. From Codec2Client, Interface and Component objects can
54  * be created by calling createComponent() and createInterface().
55  *
56  * createComponent() takes a Listener object, which must be implemented by the
57  * user.
58  *
59  * At the present, createBlockPool() is the only method that yields a
60  * Configurable object. Note, however, that Interface, Component and
61  * Codec2Client are all subclasses of Configurable.
62  */
63 
64 // Forward declaration of relevant HIDL interfaces
65 
66 namespace android::hardware::media::c2::V1_0 {
67 struct IConfigurable;
68 struct IComponent;
69 struct IComponentInterface;
70 struct IComponentStore;
71 struct IInputSink;
72 struct IInputSurface;
73 struct IInputSurfaceConnection;
74 }  // namespace android::hardware::media::c2::V1_0
75 
76 namespace android::hardware::media::c2::V1_1 {
77 struct IComponent;
78 struct IComponentStore;
79 }  // namespace android::hardware::media::c2::V1_1
80 
81 namespace android::hardware::media::bufferpool::V2_0 {
82 struct IClientManager;
83 }  // namespace android::hardware::media::bufferpool::V2_0
84 
85 namespace android::hardware::graphics::bufferqueue::V1_0 {
86 struct IGraphicBufferProducer;
87 }  // android::hardware::graphics::bufferqueue::V1_0
88 
89 namespace android::hardware::graphics::bufferqueue::V2_0 {
90 struct IGraphicBufferProducer;
91 }  // android::hardware::graphics::bufferqueue::V2_0
92 
93 namespace android::hardware::media::omx::V1_0 {
94 struct IGraphicBufferSource;
95 }  // namespace android::hardware::media::omx::V1_0
96 
97 namespace android {
98 
99 // This class is supposed to be called Codec2Client::Configurable, but forward
100 // declaration of an inner class is not possible.
101 struct Codec2ConfigurableClient {
102 
103     typedef ::android::hardware::media::c2::V1_0::IConfigurable Base;
104 
105     const C2String& getName() const;
106 
107     c2_status_t query(
108             const std::vector<C2Param*>& stackParams,
109             const std::vector<C2Param::Index> &heapParamIndices,
110             c2_blocking_t mayBlock,
111             std::vector<std::unique_ptr<C2Param>>* const heapParams) const;
112 
113     c2_status_t config(
114             const std::vector<C2Param*> &params,
115             c2_blocking_t mayBlock,
116             std::vector<std::unique_ptr<C2SettingResult>>* const failures);
117 
118     c2_status_t querySupportedParams(
119             std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
120             ) const;
121 
122     c2_status_t querySupportedValues(
123             std::vector<C2FieldSupportedValuesQuery>& fields,
124             c2_blocking_t mayBlock) const;
125 
126     // base cannot be null.
127     Codec2ConfigurableClient(const sp<Base>& base);
128 
129 protected:
130     sp<Base> mBase;
131     C2String mName;
132 
133     friend struct Codec2Client;
134 };
135 
136 struct Codec2Client : public Codec2ConfigurableClient {
137 
138     typedef ::android::hardware::media::c2::V1_0::IComponentStore Base1_0;
139     typedef ::android::hardware::media::c2::V1_1::IComponentStore Base1_1;
140     typedef Base1_0 Base;
141 
142     struct Listener;
143 
144     typedef Codec2ConfigurableClient Configurable;
145 
146     struct Component;
147 
148     struct Interface;
149 
150     struct InputSurface;
151 
152     struct InputSurfaceConnection;
153 
154     typedef Codec2Client Store;
155 
156     sp<Base> const& getBase() const;
157     sp<Base1_0> const& getBase1_0() const;
158     sp<Base1_1> const& getBase1_1() const;
159 
160     std::string const& getServiceName() const;
161 
162     c2_status_t createComponent(
163             C2String const& name,
164             std::shared_ptr<Listener> const& listener,
165             std::shared_ptr<Component>* const component);
166 
167     c2_status_t createInterface(
168             C2String const& name,
169             std::shared_ptr<Interface>* const interface);
170 
171     c2_status_t createInputSurface(
172             std::shared_ptr<InputSurface>* const inputSurface);
173 
174     std::vector<C2Component::Traits> const& listComponents() const;
175 
176     c2_status_t copyBuffer(
177             std::shared_ptr<C2Buffer> const& src,
178             std::shared_ptr<C2Buffer> const& dst);
179 
180     std::shared_ptr<C2ParamReflector> getParamReflector();
181 
182     // Returns the list of IComponentStore service names that are available on
183     // the device. This list is specified at the build time in manifest files.
184     // Note: A software service will have "_software" as a suffix.
185     static std::vector<std::string> const& GetServiceNames();
186 
187     // Create a client to a service with a given name.
188     //
189     // After a client to the service is successfully created, if
190     // setAsPreferredCodec2ComponentStore is true, the component store that the
191     // service hosts will be set as the preferred C2ComponentStore for this
192     // process. (See SetPreferredCodec2ComponentStore() for more information.)
193     static std::shared_ptr<Codec2Client> CreateFromService(
194             char const* name,
195             bool setAsPreferredCodec2ComponentStore = false);
196 
197     // Get clients to all services.
198     static std::vector<std::shared_ptr<Codec2Client>> CreateFromAllServices();
199 
200     // Try to create a component with a given name from all known
201     // IComponentStore services. numberOfAttempts determines the number of times
202     // to retry the HIDL call if the transaction fails.
203     static std::shared_ptr<Component> CreateComponentByName(
204             char const* componentName,
205             std::shared_ptr<Listener> const& listener,
206             std::shared_ptr<Codec2Client>* owner = nullptr,
207             size_t numberOfAttempts = 10);
208 
209     // Try to create a component interface with a given name from all known
210     // IComponentStore services. numberOfAttempts determines the number of times
211     // to retry the HIDL call if the transaction fails.
212     static std::shared_ptr<Interface> CreateInterfaceByName(
213             char const* interfaceName,
214             std::shared_ptr<Codec2Client>* owner = nullptr,
215             size_t numberOfAttempts = 10);
216 
217     // List traits from all known IComponentStore services.
218     static std::vector<C2Component::Traits> const& ListComponents();
219 
220     // Create an input surface.
221     static std::shared_ptr<InputSurface> CreateInputSurface(
222             char const* serviceName = nullptr);
223 
224     // base cannot be null.
225     Codec2Client(sp<Base> const& base, size_t serviceIndex);
226 
227 protected:
228     sp<Base1_0> mBase1_0;
229     sp<Base1_1> mBase1_1;
230 
231     // Finds the first store where the predicate returns C2_OK and returns the
232     // last predicate result. The predicate will be tried on all stores. The
233     // function will return C2_OK the first time the predicate returns C2_OK,
234     // or it will return the value from the last time that predicate is tried.
235     // (The latter case corresponds to a failure on every store.) The order of
236     // the stores to try is the same as the return value of GetServiceNames().
237     //
238     // key is used to remember the last store with which the predicate last
239     // succeeded. If the last successful store is cached, it will be tried
240     // first before all the stores are tried. Note that the last successful
241     // store will be tried twice---first before all the stores, and another time
242     // with all the stores.
243     //
244     // If an attempt to evaluate the predicate results in a transaction failure,
245     // repeated attempts will be made until the predicate returns without a
246     // transaction failure or numberOfAttempts attempts have been made.
247     static c2_status_t ForAllServices(
248             const std::string& key,
249             size_t numberOfAttempts,
250             std::function<c2_status_t(std::shared_ptr<Codec2Client> const&)>
251                 predicate);
252 
253     size_t mServiceIndex;
254     mutable std::vector<C2Component::Traits> mTraitsList;
255 
256     sp<::android::hardware::media::bufferpool::V2_0::IClientManager>
257             mHostPoolManager;
258 
259     static std::shared_ptr<Codec2Client> _CreateFromIndex(size_t index);
260 
261     std::vector<C2Component::Traits> _listComponents(bool* success) const;
262 
263     class Cache;
264 };
265 
266 struct Codec2Client::Interface : public Codec2Client::Configurable {
267 
268     typedef ::android::hardware::media::c2::V1_0::IComponentInterface Base;
269 
270     Interface(const sp<Base>& base);
271 
272 protected:
273     sp<Base> mBase;
274 };
275 
276 struct Codec2Client::Listener {
277 
278     // This is called when the component produces some output.
279     virtual void onWorkDone(
280             const std::weak_ptr<Component>& comp,
281             std::list<std::unique_ptr<C2Work>>& workItems) = 0;
282 
283     // This is called when the component goes into a tripped state.
284     virtual void onTripped(
285             const std::weak_ptr<Component>& comp,
286             const std::vector<std::shared_ptr<C2SettingResult>>& settingResults
287             ) = 0;
288 
289     // This is called when the component encounters an error.
290     virtual void onError(
291             const std::weak_ptr<Component>& comp,
292             uint32_t errorCode) = 0;
293 
294     // This is called when the process that hosts the component shuts down
295     // unexpectedly.
296     virtual void onDeath(
297             const std::weak_ptr<Component>& comp) = 0;
298 
299     // This is called when an input buffer is no longer in use by the codec.
300     // Input buffers that have been returned by onWorkDone() or flush() will not
301     // trigger a call to this function.
302     virtual void onInputBufferDone(
303             uint64_t frameIndex, size_t arrayIndex) = 0;
304 
305     // This is called when the component becomes aware of a frame being
306     // rendered.
307     virtual void onFrameRendered(
308             uint64_t bufferQueueId,
309             int32_t slotId,
310             int64_t timestampNs) = 0;
311 
312     virtual ~Listener();
313 
314 };
315 
316 struct Codec2Client::Component : public Codec2Client::Configurable {
317 
318     typedef ::android::hardware::media::c2::V1_0::IComponent Base1_0;
319     typedef ::android::hardware::media::c2::V1_1::IComponent Base1_1;
320     typedef Base1_0 Base;
321 
322     c2_status_t createBlockPool(
323             C2Allocator::id_t id,
324             C2BlockPool::local_id_t* blockPoolId,
325             std::shared_ptr<Configurable>* configurable);
326 
327     c2_status_t destroyBlockPool(
328             C2BlockPool::local_id_t localId);
329 
330     c2_status_t queue(
331             std::list<std::unique_ptr<C2Work>>* const items);
332 
333     c2_status_t flush(
334             C2Component::flush_mode_t mode,
335             std::list<std::unique_ptr<C2Work>>* const flushedWork);
336 
337     c2_status_t drain(C2Component::drain_mode_t mode);
338 
339     c2_status_t start();
340 
341     c2_status_t stop();
342 
343     c2_status_t reset();
344 
345     c2_status_t release();
346 
347     /**
348      * Use tunneling.
349      *
350      * On success, @p sidebandHandle will be a newly allocated native handle.
351      * File descriptors in @p sidebandHandle must be closed and
352      * @p sidebandHandle itself must be deleted afterwards.
353      */
354     c2_status_t configureVideoTunnel(
355             uint32_t avSyncHwId,
356             native_handle_t** sidebandHandle);
357 
358     typedef ::android::
359             IGraphicBufferProducer IGraphicBufferProducer;
360     typedef IGraphicBufferProducer::
361             QueueBufferInput QueueBufferInput;
362     typedef IGraphicBufferProducer::
363             QueueBufferOutput QueueBufferOutput;
364 
365     typedef ::android::hardware::graphics::bufferqueue::V1_0::
366             IGraphicBufferProducer HGraphicBufferProducer1;
367     typedef ::android::hardware::graphics::bufferqueue::V2_0::
368             IGraphicBufferProducer HGraphicBufferProducer2;
369     typedef ::android::hardware::media::omx::V1_0::
370             IGraphicBufferSource HGraphicBufferSource;
371 
372     // Set the output surface to be used with a blockpool previously created by
373     // createBlockPool().
374     c2_status_t setOutputSurface(
375             C2BlockPool::local_id_t blockPoolId,
376             const sp<IGraphicBufferProducer>& surface,
377             uint32_t generation);
378 
379     // Extract a slot number from of the block, then call
380     // IGraphicBufferProducer::queueBuffer().
381     //
382     // If the output surface has not been set, NO_INIT will be returned.
383     //
384     // If the block does not come from a bufferqueue-based blockpool,
385     // attachBuffer() will be called, followed by queueBuffer().
386     //
387     // If the block has a bqId that does not match the id of the output surface,
388     // DEAD_OBJECT will be returned.
389     //
390     // If the call to queueBuffer() is successful but the block cannot be
391     // associated to the output surface for automatic cancellation upon
392     // destruction, UNKNOWN_ERROR will be returned.
393     //
394     // Otherwise, the return value from queueBuffer() will be returned.
395     status_t queueToOutputSurface(
396             const C2ConstGraphicBlock& block,
397             const QueueBufferInput& input,
398             QueueBufferOutput* output);
399 
400     // Connect to a given InputSurface.
401     c2_status_t connectToInputSurface(
402             const std::shared_ptr<InputSurface>& inputSurface,
403             std::shared_ptr<InputSurfaceConnection>* connection);
404 
405     c2_status_t connectToOmxInputSurface(
406             const sp<HGraphicBufferProducer1>& producer,
407             const sp<HGraphicBufferSource>& source,
408             std::shared_ptr<InputSurfaceConnection>* connection);
409 
410     c2_status_t disconnectFromInputSurface();
411 
412     // base cannot be null.
413     Component(const sp<Base>& base);
414     Component(const sp<Base1_1>& base);
415 
416     ~Component();
417 
418 protected:
419     sp<Base1_0> mBase1_0;
420     sp<Base1_1> mBase1_1;
421 
422     struct BufferPoolSender;
423     std::unique_ptr<BufferPoolSender> mBufferPoolSender;
424 
425     struct OutputBufferQueue;
426     std::unique_ptr<OutputBufferQueue> mOutputBufferQueue;
427 
428     static c2_status_t setDeathListener(
429             const std::shared_ptr<Component>& component,
430             const std::shared_ptr<Listener>& listener);
431     sp<::android::hardware::hidl_death_recipient> mDeathRecipient;
432 
433     friend struct Codec2Client;
434 
435     struct HidlListener;
436     void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems);
437 
438 };
439 
440 struct Codec2Client::InputSurface : public Codec2Client::Configurable {
441 public:
442     typedef ::android::hardware::media::c2::V1_0::IInputSurface Base;
443 
444     typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection
445             ConnectionBase;
446 
447     typedef Codec2Client::InputSurfaceConnection Connection;
448 
449     typedef ::android::IGraphicBufferProducer IGraphicBufferProducer;
450 
451     sp<IGraphicBufferProducer> getGraphicBufferProducer() const;
452 
453     // Return the underlying IInputSurface.
454     sp<Base> getHalInterface() const;
455 
456     // base cannot be null.
457     InputSurface(const sp<Base>& base);
458 
459 protected:
460     sp<Base> mBase;
461 
462     sp<IGraphicBufferProducer> mGraphicBufferProducer;
463 
464     friend struct Codec2Client;
465     friend struct Component;
466 };
467 
468 struct Codec2Client::InputSurfaceConnection : public Codec2Client::Configurable {
469 
470     typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection Base;
471 
472     c2_status_t disconnect();
473 
474     // base cannot be null.
475     InputSurfaceConnection(const sp<Base>& base);
476 
477 protected:
478     sp<Base> mBase;
479 
480     friend struct Codec2Client::InputSurface;
481 };
482 
483 }  // namespace android
484 
485 #endif  // CODEC2_HIDL_CLIENT_H
486 
487