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 #ifndef CODEC2_HIDL_CLIENT_H_
18 #define CODEC2_HIDL_CLIENT_H_
19 
20 #include <gui/IGraphicBufferProducer.h>
21 #include <codec2/hidl/1.0/types.h>
22 
23 #include <C2PlatformSupport.h>
24 #include <C2Component.h>
25 #include <C2Buffer.h>
26 #include <C2Param.h>
27 #include <C2.h>
28 
29 #include <hidl/HidlSupport.h>
30 #include <utils/StrongPointer.h>
31 
32 #include <functional>
33 #include <map>
34 #include <memory>
35 #include <mutex>
36 
37 /**
38  * This file contains minimal interfaces for the framework to access Codec2.0.
39  *
40  * Codec2Client is the main class that contains the following inner classes:
41  * - Listener
42  * - Configurable
43  * - Interface
44  * - Component
45  *
46  * Classes in Codec2Client, interfaces in Codec2.0, and  HIDL interfaces are
47  * related as follows:
48  * - Codec2Client <==> C2ComponentStore <==> IComponentStore
49  * - Codec2Client::Listener <==> C2Component::Listener <==> IComponentListener
50  * - Codec2Client::Configurable <==> [No equivalent] <==> IConfigurable
51  * - Codec2Client::Interface <==> C2ComponentInterface <==> IComponentInterface
52  * - Codec2Client::Component <==> C2Component <==> IComponent
53  *
54  * The entry point is Codec2Client::CreateFromService(), which creates a
55  * Codec2Client object. From Codec2Client, Interface and Component objects can
56  * be created by calling createComponent() and createInterface().
57  *
58  * createComponent() takes a Listener object, which must be implemented by the
59  * user.
60  *
61  * At the present, createBlockPool() is the only method that yields a
62  * Configurable object. Note, however, that Interface, Component and
63  * Codec2Client are all subclasses of Configurable.
64  */
65 
66 // Forward declaration of Codec2.0 HIDL interfaces
67 namespace hardware {
68 namespace google {
69 namespace media {
70 namespace c2 {
71 namespace V1_0 {
72 struct IConfigurable;
73 struct IComponentInterface;
74 struct IComponent;
75 struct IComponentStore;
76 struct IInputSurface;
77 struct IInputSurfaceConnection;
78 } // namespace V1_0
79 } // namespace c2
80 } // namespace media
81 } // namespace google
82 } // namespace hardware
83 
84 namespace android {
85 namespace hardware {
86 namespace media {
87 namespace bufferpool {
88 namespace V1_0 {
89 struct IClientManager;
90 } // namespace V1_0
91 } // namespace bufferpool
92 } // namespace media
93 } // namespace hardware
94 } // namespace android
95 
96 // Forward declarations of other classes
97 namespace android {
98 namespace hardware {
99 namespace graphics {
100 namespace bufferqueue {
101 namespace V1_0 {
102 struct IGraphicBufferProducer;
103 } // namespace V1_0
104 } // namespace bufferqueue
105 } // namespace graphics
106 namespace media {
107 namespace omx {
108 namespace V1_0 {
109 struct IGraphicBufferSource;
110 } // namespace V1_0
111 } // namespace omx
112 } // namespace media
113 } // namespace hardware
114 } // namespace android
115 
116 namespace android {
117 
118 // This class is supposed to be called Codec2Client::Configurable, but forward
119 // declaration of an inner class is not possible.
120 struct Codec2ConfigurableClient {
121 
122     typedef ::hardware::google::media::c2::V1_0::IConfigurable Base;
123 
124     const C2String& getName() const;
125 
126     c2_status_t query(
127             const std::vector<C2Param*>& stackParams,
128             const std::vector<C2Param::Index> &heapParamIndices,
129             c2_blocking_t mayBlock,
130             std::vector<std::unique_ptr<C2Param>>* const heapParams) const;
131 
132     c2_status_t config(
133             const std::vector<C2Param*> &params,
134             c2_blocking_t mayBlock,
135             std::vector<std::unique_ptr<C2SettingResult>>* const failures);
136 
137     c2_status_t querySupportedParams(
138             std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
139             ) const;
140 
141     c2_status_t querySupportedValues(
142             std::vector<C2FieldSupportedValuesQuery>& fields,
143             c2_blocking_t mayBlock) const;
144 
145     // base cannot be null.
146     Codec2ConfigurableClient(const sp<Base>& base);
147 
148 protected:
149     C2String mName;
150     sp<Base> mBase;
151 
152     Base* base() const;
153 
154     friend struct Codec2Client;
155 };
156 
157 struct Codec2Client : public Codec2ConfigurableClient {
158 
159     typedef ::hardware::google::media::c2::V1_0::IComponentStore Base;
160 
161     struct Listener;
162 
163     typedef Codec2ConfigurableClient Configurable;
164 
165     typedef Configurable Interface; // These two types may diverge in the future.
166 
167     struct Component;
168 
169     struct InputSurface;
170 
171     struct InputSurfaceConnection;
172 
173     typedef Codec2Client Store;
174 
getInstanceNameCodec2Client175     std::string getInstanceName() const { return mInstanceName; }
176 
177     c2_status_t createComponent(
178             const C2String& name,
179             const std::shared_ptr<Listener>& listener,
180             std::shared_ptr<Component>* const component);
181 
182     c2_status_t createInterface(
183             const C2String& name,
184             std::shared_ptr<Interface>* const interface);
185 
186     c2_status_t createInputSurface(
187             std::shared_ptr<InputSurface>* const inputSurface);
188 
189     const std::vector<C2Component::Traits>& listComponents() const;
190 
191     c2_status_t copyBuffer(
192             const std::shared_ptr<C2Buffer>& src,
193             const std::shared_ptr<C2Buffer>& dst);
194 
195     std::shared_ptr<C2ParamReflector> getParamReflector();
196 
197     static std::shared_ptr<Codec2Client> CreateFromService(
198             const char* instanceName,
199             bool waitForService = true);
200 
201     // Try to create a component with a given name from all known
202     // IComponentStore services.
203     static std::shared_ptr<Component> CreateComponentByName(
204             const char* componentName,
205             const std::shared_ptr<Listener>& listener,
206             std::shared_ptr<Codec2Client>* owner = nullptr);
207 
208     // Try to create a component interface with a given name from all known
209     // IComponentStore services.
210     static std::shared_ptr<Interface> CreateInterfaceByName(
211             const char* interfaceName,
212             std::shared_ptr<Codec2Client>* owner = nullptr);
213 
214     // List traits from all known IComponentStore services.
215     static const std::vector<C2Component::Traits>& ListComponents();
216 
217     // base cannot be null.
218     Codec2Client(const sp<Base>& base, std::string instanceName);
219 
220 protected:
221     Base* base() const;
222 
223     // Finds the first store where the predicate returns OK, and returns the last
224     // predicate result. Uses key to remember the last store found, and if cached,
225     // it tries that store before trying all stores (one retry).
226     static c2_status_t ForAllStores(
227             const std::string& key,
228             std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)> predicate);
229 
230     mutable std::mutex mMutex;
231     mutable bool mListed;
232     std::string mInstanceName;
233     mutable std::vector<C2Component::Traits> mTraitsList;
234     mutable std::vector<std::unique_ptr<std::vector<std::string>>>
235             mAliasesBuffer;
236 
237     sp<::android::hardware::media::bufferpool::V1_0::IClientManager>
238             mHostPoolManager;
239 };
240 
241 struct Codec2Client::Listener {
242 
243     virtual void onWorkDone(
244             const std::weak_ptr<Component>& comp,
245             std::list<std::unique_ptr<C2Work>>& workItems) = 0;
246 
247     virtual void onTripped(
248             const std::weak_ptr<Component>& comp,
249             const std::vector<std::shared_ptr<C2SettingResult>>& settingResults
250             ) = 0;
251 
252     virtual void onError(
253             const std::weak_ptr<Component>& comp,
254             uint32_t errorCode) = 0;
255 
256     virtual void onDeath(
257             const std::weak_ptr<Component>& comp) = 0;
258 
259     struct RenderedFrame {
260         uint64_t bufferQueueId;
261         int32_t slotId;
262         int64_t timestampNs;
263     };
264 
265     virtual void onFramesRendered(
266             const std::vector<RenderedFrame>& renderedFrames) = 0;
267 
268     virtual ~Listener();
269 
270 };
271 
272 struct Codec2Client::Component : public Codec2Client::Configurable {
273 
274     typedef ::hardware::google::media::c2::V1_0::IComponent Base;
275 
276     c2_status_t createBlockPool(
277             C2Allocator::id_t id,
278             C2BlockPool::local_id_t* blockPoolId,
279             std::shared_ptr<Configurable>* configurable);
280 
281     c2_status_t destroyBlockPool(
282             C2BlockPool::local_id_t localId);
283 
284     c2_status_t queue(
285             std::list<std::unique_ptr<C2Work>>* const items);
286 
287     c2_status_t flush(
288             C2Component::flush_mode_t mode,
289             std::list<std::unique_ptr<C2Work>>* const flushedWork);
290 
291     c2_status_t drain(C2Component::drain_mode_t mode);
292 
293     c2_status_t start();
294 
295     c2_status_t stop();
296 
297     c2_status_t reset();
298 
299     c2_status_t release();
300 
301     typedef ::android::
302             IGraphicBufferProducer IGraphicBufferProducer;
303     typedef IGraphicBufferProducer::
304             QueueBufferInput QueueBufferInput;
305     typedef IGraphicBufferProducer::
306             QueueBufferOutput QueueBufferOutput;
307 
308     typedef ::android::hardware::graphics::bufferqueue::V1_0::
309             IGraphicBufferProducer HGraphicBufferProducer;
310     typedef ::android::hardware::media::omx::V1_0::
311             IGraphicBufferSource HGraphicBufferSource;
312 
313     // Set the output surface to be used with a blockpool previously created by
314     // createBlockPool().
315     c2_status_t setOutputSurface(
316             C2BlockPool::local_id_t blockPoolId,
317             const sp<IGraphicBufferProducer>& surface,
318             uint32_t generation);
319 
320     // Extract a slot number from of the block, then call
321     // IGraphicBufferProducer::queueBuffer().
322     //
323     // If the output surface has not been set, NO_INIT will be returned.
324     //
325     // If the block does not come from a bufferqueue-based blockpool,
326     // attachBuffer() will be called, followed by queueBuffer().
327     //
328     // If the block has a bqId that does not match the id of the output surface,
329     // DEAD_OBJECT will be returned.
330     //
331     // If the call to queueBuffer() is successful but the block cannot be
332     // associated to the output surface for automatic cancellation upon
333     // destruction, UNKNOWN_ERROR will be returned.
334     //
335     // Otherwise, the return value from queueBuffer() will be returned.
336     status_t queueToOutputSurface(
337             const C2ConstGraphicBlock& block,
338             const QueueBufferInput& input,
339             QueueBufferOutput* output);
340 
341     c2_status_t connectToOmxInputSurface(
342             const sp<HGraphicBufferProducer>& producer,
343             const sp<HGraphicBufferSource>& source);
344 
345     c2_status_t disconnectFromInputSurface();
346 
347     void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems);
348 
349     // base cannot be null.
350     Component(const sp<Base>& base);
351 
352     ~Component();
353 
354 protected:
355     Base* base() const;
356 
357     mutable std::mutex mInputBuffersMutex;
358     mutable std::map<uint64_t, std::vector<std::shared_ptr<C2Buffer>>>
359             mInputBuffers;
360 
361     ::hardware::google::media::c2::V1_0::utils::DefaultBufferPoolSender
362             mBufferPoolSender;
363 
364     std::mutex mOutputBufferQueueMutex;
365     sp<IGraphicBufferProducer> mOutputIgbp;
366     uint64_t mOutputBqId;
367     uint32_t mOutputGeneration;
368 
369     static c2_status_t setDeathListener(
370             const std::shared_ptr<Component>& component,
371             const std::shared_ptr<Listener>& listener);
372     sp<::android::hardware::hidl_death_recipient> mDeathRecipient;
373 
374     friend struct Codec2Client;
375 };
376 
377 struct Codec2Client::InputSurface {
378 public:
379     typedef ::hardware::google::media::c2::V1_0::IInputSurface Base;
380 
381     typedef ::hardware::google::media::c2::V1_0::IInputSurfaceConnection
382             ConnectionBase;
383 
384     typedef Codec2Client::InputSurfaceConnection Connection;
385 
386     typedef ::android::IGraphicBufferProducer IGraphicBufferProducer;
387 
388     c2_status_t connectToComponent(
389             const std::shared_ptr<Component>& component,
390             std::shared_ptr<Connection>* connection);
391 
392     std::shared_ptr<Configurable> getConfigurable() const;
393 
394     const sp<IGraphicBufferProducer>& getGraphicBufferProducer() const;
395 
396     // base cannot be null.
397     InputSurface(const sp<Base>& base);
398 
399 protected:
400     Base* base() const;
401     sp<Base> mBase;
402 
403     sp<IGraphicBufferProducer> mGraphicBufferProducer;
404 
405     friend struct Codec2Client;
406     friend struct Component;
407 };
408 
409 struct Codec2Client::InputSurfaceConnection {
410 
411     typedef ::hardware::google::media::c2::V1_0::IInputSurfaceConnection Base;
412 
413     c2_status_t disconnect();
414 
415     // base cannot be null.
416     InputSurfaceConnection(const sp<Base>& base);
417 
418 protected:
419     Base* base() const;
420     sp<Base> mBase;
421 
422     friend struct Codec2Client::InputSurface;
423 };
424 
425 }  // namespace android
426 
427 #endif  // CODEC2_HIDL_CLIENT_H_
428 
429