| /* |
| * Copyright 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef CODEC2_HIDL_CLIENT_H |
| #define CODEC2_HIDL_CLIENT_H |
| |
| #include <gui/IGraphicBufferProducer.h> |
| #include <codec2/hidl/1.0/ClientBlockHelper.h> |
| #include <C2PlatformSupport.h> |
| #include <C2Component.h> |
| #include <C2Buffer.h> |
| #include <C2Param.h> |
| #include <C2.h> |
| |
| #include <hidl/HidlSupport.h> |
| #include <utils/StrongPointer.h> |
| |
| #include <functional> |
| #include <map> |
| #include <memory> |
| #include <mutex> |
| |
| /** |
| * This file contains minimal interfaces for the framework to access Codec2.0. |
| * |
| * Codec2Client is the main class that contains the following inner classes: |
| * - Listener |
| * - Configurable |
| * - Interface |
| * - Component |
| * |
| * Classes in Codec2Client, interfaces in Codec2.0, and HIDL interfaces are |
| * related as follows: |
| * - Codec2Client <==> C2ComponentStore <==> IComponentStore |
| * - Codec2Client::Listener <==> C2Component::Listener <==> IComponentListener |
| * - Codec2Client::Configurable <==> [No equivalent] <==> IConfigurable |
| * - Codec2Client::Interface <==> C2ComponentInterface <==> IComponentInterface |
| * - Codec2Client::Component <==> C2Component <==> IComponent |
| * |
| * The entry point is Codec2Client::CreateFromService(), which creates a |
| * Codec2Client object. From Codec2Client, Interface and Component objects can |
| * be created by calling createComponent() and createInterface(). |
| * |
| * createComponent() takes a Listener object, which must be implemented by the |
| * user. |
| * |
| * At the present, createBlockPool() is the only method that yields a |
| * Configurable object. Note, however, that Interface, Component and |
| * Codec2Client are all subclasses of Configurable. |
| */ |
| |
| // Forward declaration of relevant HIDL interfaces |
| |
| namespace android::hardware::media::c2::V1_0 { |
| struct IConfigurable; |
| struct IComponent; |
| struct IComponentInterface; |
| struct IComponentStore; |
| struct IInputSink; |
| struct IInputSurface; |
| struct IInputSurfaceConnection; |
| } // namespace android::hardware::media::c2::V1_0 |
| |
| namespace android::hardware::media::bufferpool::V2_0 { |
| struct IClientManager; |
| } // namespace android::hardware::media::bufferpool::V2_0 |
| |
| namespace android::hardware::graphics::bufferqueue::V1_0 { |
| struct IGraphicBufferProducer; |
| } // android::hardware::graphics::bufferqueue::V1_0 |
| |
| namespace android::hardware::media::omx::V1_0 { |
| struct IGraphicBufferSource; |
| } // namespace android::hardware::media::omx::V1_0 |
| |
| namespace android { |
| |
| // This class is supposed to be called Codec2Client::Configurable, but forward |
| // declaration of an inner class is not possible. |
| struct Codec2ConfigurableClient { |
| |
| typedef ::android::hardware::media::c2::V1_0::IConfigurable Base; |
| |
| const C2String& getName() const; |
| |
| c2_status_t query( |
| const std::vector<C2Param*>& stackParams, |
| const std::vector<C2Param::Index> &heapParamIndices, |
| c2_blocking_t mayBlock, |
| std::vector<std::unique_ptr<C2Param>>* const heapParams) const; |
| |
| c2_status_t config( |
| const std::vector<C2Param*> ¶ms, |
| c2_blocking_t mayBlock, |
| std::vector<std::unique_ptr<C2SettingResult>>* const failures); |
| |
| c2_status_t querySupportedParams( |
| std::vector<std::shared_ptr<C2ParamDescriptor>>* const params |
| ) const; |
| |
| c2_status_t querySupportedValues( |
| std::vector<C2FieldSupportedValuesQuery>& fields, |
| c2_blocking_t mayBlock) const; |
| |
| // base cannot be null. |
| Codec2ConfigurableClient(const sp<Base>& base); |
| |
| protected: |
| sp<Base> mBase; |
| C2String mName; |
| |
| friend struct Codec2Client; |
| }; |
| |
| struct Codec2Client : public Codec2ConfigurableClient { |
| |
| typedef ::android::hardware::media::c2::V1_0::IComponentStore Base; |
| |
| struct Listener; |
| |
| typedef Codec2ConfigurableClient Configurable; |
| |
| struct Component; |
| |
| struct Interface; |
| |
| struct InputSurface; |
| |
| struct InputSurfaceConnection; |
| |
| typedef Codec2Client Store; |
| |
| sp<Base> const& getBase() const; |
| |
| std::string const& getServiceName() const; |
| |
| c2_status_t createComponent( |
| C2String const& name, |
| std::shared_ptr<Listener> const& listener, |
| std::shared_ptr<Component>* const component); |
| |
| c2_status_t createInterface( |
| C2String const& name, |
| std::shared_ptr<Interface>* const interface); |
| |
| c2_status_t createInputSurface( |
| std::shared_ptr<InputSurface>* const inputSurface); |
| |
| std::vector<C2Component::Traits> const& listComponents() const; |
| |
| c2_status_t copyBuffer( |
| std::shared_ptr<C2Buffer> const& src, |
| std::shared_ptr<C2Buffer> const& dst); |
| |
| std::shared_ptr<C2ParamReflector> getParamReflector(); |
| |
| // Returns the list of IComponentStore service names that are available on |
| // the device. This list is specified at the build time in manifest files. |
| // Note: A software service will have "_software" as a suffix. |
| static std::vector<std::string> const& GetServiceNames(); |
| |
| // Create a service with a given service name. |
| static std::shared_ptr<Codec2Client> CreateFromService(char const* name); |
| |
| // Get clients to all services. |
| static std::vector<std::shared_ptr<Codec2Client>> CreateFromAllServices(); |
| |
| // Try to create a component with a given name from all known |
| // IComponentStore services. numberOfAttempts determines the number of times |
| // to retry the HIDL call if the transaction fails. |
| static std::shared_ptr<Component> CreateComponentByName( |
| char const* componentName, |
| std::shared_ptr<Listener> const& listener, |
| std::shared_ptr<Codec2Client>* owner = nullptr, |
| size_t numberOfAttempts = 10); |
| |
| // Try to create a component interface with a given name from all known |
| // IComponentStore services. numberOfAttempts determines the number of times |
| // to retry the HIDL call if the transaction fails. |
| static std::shared_ptr<Interface> CreateInterfaceByName( |
| char const* interfaceName, |
| std::shared_ptr<Codec2Client>* owner = nullptr, |
| size_t numberOfAttempts = 10); |
| |
| // List traits from all known IComponentStore services. |
| static std::vector<C2Component::Traits> const& ListComponents(); |
| |
| // Create an input surface. |
| static std::shared_ptr<InputSurface> CreateInputSurface( |
| char const* serviceName = nullptr); |
| |
| // base cannot be null. |
| Codec2Client(sp<Base> const& base, size_t serviceIndex); |
| |
| protected: |
| sp<Base> mBase; |
| |
| // Finds the first store where the predicate returns OK, and returns the last |
| // predicate result. Uses key to remember the last store found, and if cached, |
| // it tries that store before trying all stores (one retry). |
| static c2_status_t ForAllServices( |
| const std::string& key, |
| std::function<c2_status_t(std::shared_ptr<Codec2Client> const&)> |
| predicate); |
| |
| size_t mServiceIndex; |
| mutable std::vector<C2Component::Traits> mTraitsList; |
| |
| sp<::android::hardware::media::bufferpool::V2_0::IClientManager> |
| mHostPoolManager; |
| |
| static std::shared_ptr<Codec2Client> _CreateFromIndex(size_t index); |
| |
| std::vector<C2Component::Traits> _listComponents(bool* success) const; |
| |
| class Cache; |
| }; |
| |
| struct Codec2Client::Interface : public Codec2Client::Configurable { |
| |
| typedef ::android::hardware::media::c2::V1_0::IComponentInterface Base; |
| |
| Interface(const sp<Base>& base); |
| |
| protected: |
| sp<Base> mBase; |
| }; |
| |
| struct Codec2Client::Listener { |
| |
| // This is called when the component produces some output. |
| virtual void onWorkDone( |
| const std::weak_ptr<Component>& comp, |
| std::list<std::unique_ptr<C2Work>>& workItems) = 0; |
| |
| // This is called when the component goes into a tripped state. |
| virtual void onTripped( |
| const std::weak_ptr<Component>& comp, |
| const std::vector<std::shared_ptr<C2SettingResult>>& settingResults |
| ) = 0; |
| |
| // This is called when the component encounters an error. |
| virtual void onError( |
| const std::weak_ptr<Component>& comp, |
| uint32_t errorCode) = 0; |
| |
| // This is called when the process that hosts the component shuts down |
| // unexpectedly. |
| virtual void onDeath( |
| const std::weak_ptr<Component>& comp) = 0; |
| |
| // This is called when an input buffer is no longer in use by the codec. |
| // Input buffers that have been returned by onWorkDone() or flush() will not |
| // trigger a call to this function. |
| virtual void onInputBufferDone( |
| uint64_t frameIndex, size_t arrayIndex) = 0; |
| |
| // This is called when the component becomes aware of a frame being |
| // rendered. |
| virtual void onFrameRendered( |
| uint64_t bufferQueueId, |
| int32_t slotId, |
| int64_t timestampNs) = 0; |
| |
| virtual ~Listener(); |
| |
| }; |
| |
| struct Codec2Client::Component : public Codec2Client::Configurable { |
| |
| typedef ::android::hardware::media::c2::V1_0::IComponent Base; |
| |
| c2_status_t createBlockPool( |
| C2Allocator::id_t id, |
| C2BlockPool::local_id_t* blockPoolId, |
| std::shared_ptr<Configurable>* configurable); |
| |
| c2_status_t destroyBlockPool( |
| C2BlockPool::local_id_t localId); |
| |
| c2_status_t queue( |
| std::list<std::unique_ptr<C2Work>>* const items); |
| |
| c2_status_t flush( |
| C2Component::flush_mode_t mode, |
| std::list<std::unique_ptr<C2Work>>* const flushedWork); |
| |
| c2_status_t drain(C2Component::drain_mode_t mode); |
| |
| c2_status_t start(); |
| |
| c2_status_t stop(); |
| |
| c2_status_t reset(); |
| |
| c2_status_t release(); |
| |
| typedef ::android:: |
| IGraphicBufferProducer IGraphicBufferProducer; |
| typedef IGraphicBufferProducer:: |
| QueueBufferInput QueueBufferInput; |
| typedef IGraphicBufferProducer:: |
| QueueBufferOutput QueueBufferOutput; |
| |
| typedef ::android::hardware::graphics::bufferqueue::V1_0:: |
| IGraphicBufferProducer HGraphicBufferProducer1; |
| typedef ::android::hardware::graphics::bufferqueue::V2_0:: |
| IGraphicBufferProducer HGraphicBufferProducer2; |
| typedef ::android::hardware::media::omx::V1_0:: |
| IGraphicBufferSource HGraphicBufferSource; |
| |
| // Set the output surface to be used with a blockpool previously created by |
| // createBlockPool(). |
| c2_status_t setOutputSurface( |
| C2BlockPool::local_id_t blockPoolId, |
| const sp<IGraphicBufferProducer>& surface, |
| uint32_t generation); |
| |
| // Extract a slot number from of the block, then call |
| // IGraphicBufferProducer::queueBuffer(). |
| // |
| // If the output surface has not been set, NO_INIT will be returned. |
| // |
| // If the block does not come from a bufferqueue-based blockpool, |
| // attachBuffer() will be called, followed by queueBuffer(). |
| // |
| // If the block has a bqId that does not match the id of the output surface, |
| // DEAD_OBJECT will be returned. |
| // |
| // If the call to queueBuffer() is successful but the block cannot be |
| // associated to the output surface for automatic cancellation upon |
| // destruction, UNKNOWN_ERROR will be returned. |
| // |
| // Otherwise, the return value from queueBuffer() will be returned. |
| status_t queueToOutputSurface( |
| const C2ConstGraphicBlock& block, |
| const QueueBufferInput& input, |
| QueueBufferOutput* output); |
| |
| // Connect to a given InputSurface. |
| c2_status_t connectToInputSurface( |
| const std::shared_ptr<InputSurface>& inputSurface, |
| std::shared_ptr<InputSurfaceConnection>* connection); |
| |
| c2_status_t connectToOmxInputSurface( |
| const sp<HGraphicBufferProducer1>& producer, |
| const sp<HGraphicBufferSource>& source, |
| std::shared_ptr<InputSurfaceConnection>* connection); |
| |
| c2_status_t disconnectFromInputSurface(); |
| |
| // base cannot be null. |
| Component(const sp<Base>& base); |
| |
| ~Component(); |
| |
| protected: |
| sp<Base> mBase; |
| |
| ::android::hardware::media::c2::V1_0::utils::DefaultBufferPoolSender |
| mBufferPoolSender; |
| |
| ::android::hardware::media::c2::V1_0::utils::OutputBufferQueue |
| mOutputBufferQueue; |
| |
| static c2_status_t setDeathListener( |
| const std::shared_ptr<Component>& component, |
| const std::shared_ptr<Listener>& listener); |
| sp<::android::hardware::hidl_death_recipient> mDeathRecipient; |
| |
| friend struct Codec2Client; |
| |
| struct HidlListener; |
| void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems); |
| |
| }; |
| |
| struct Codec2Client::InputSurface : public Codec2Client::Configurable { |
| public: |
| typedef ::android::hardware::media::c2::V1_0::IInputSurface Base; |
| |
| typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection |
| ConnectionBase; |
| |
| typedef Codec2Client::InputSurfaceConnection Connection; |
| |
| typedef ::android::IGraphicBufferProducer IGraphicBufferProducer; |
| |
| sp<IGraphicBufferProducer> getGraphicBufferProducer() const; |
| |
| // Return the underlying IInputSurface. |
| sp<Base> getHalInterface() const; |
| |
| // base cannot be null. |
| InputSurface(const sp<Base>& base); |
| |
| protected: |
| sp<Base> mBase; |
| |
| sp<IGraphicBufferProducer> mGraphicBufferProducer; |
| |
| friend struct Codec2Client; |
| friend struct Component; |
| }; |
| |
| struct Codec2Client::InputSurfaceConnection : public Codec2Client::Configurable { |
| |
| typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection Base; |
| |
| c2_status_t disconnect(); |
| |
| // base cannot be null. |
| InputSurfaceConnection(const sp<Base>& base); |
| |
| protected: |
| sp<Base> mBase; |
| |
| friend struct Codec2Client::InputSurface; |
| }; |
| |
| } // namespace android |
| |
| #endif // CODEC2_HIDL_CLIENT_H |
| |