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