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