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