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