Loading media/codec2/hal/client/client.cpp +89 −141 Original line number Diff line number Diff line Loading @@ -2281,30 +2281,22 @@ c2_status_t Codec2Client::createInputSurface( // Not supported for APEX. return C2_OMITTED; } if (mAidlBase) { // FIXME if (!mAidlBase) { // Only AIDL supports InputSurface. return C2_OMITTED; } c2_status_t status; Return<void> transStatus = mHidlBase1_0->createInputSurface( [&status, inputSurface]( c2_hidl::Status s, const sp<c2_hidl::IInputSurface>& i) { status = static_cast<c2_status_t>(s); if (status != C2_OK) { return; if (!IsCodec2AidlInputSurfaceSelected()) { return C2_OMITTED; } *inputSurface = std::make_shared<InputSurface>(i); }); if (!transStatus.isOk()) { LOG(ERROR) << "createInputSurface -- transaction failed."; return C2_TRANSACTION_FAILED; } else if (status != C2_OK) { LOG(DEBUG) << "createInputSurface -- call failed: " << status << "."; std::shared_ptr<c2_aidl::IInputSurface> interface; ndk::ScopedAStatus status = mAidlBase->createInputSurface(&interface); c2_status_t c2Status = GetC2Status(status, "createInputSurface"); if (c2Status != C2_OK) { LOG(ERROR) << "createInputSurface() failed: " << c2Status; return c2Status; } return status; *inputSurface = std::make_shared<InputSurface>(interface); return C2_OK; } std::vector<C2Component::Traits> const& Codec2Client::listComponents() const { Loading Loading @@ -2823,6 +2815,12 @@ std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurface( return nullptr; } std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurfaceFromInterface( const ::ndk::SpAIBinder &interface) { return std::make_shared<Codec2Client::InputSurface>( c2_aidl::IInputSurface::fromBinder(interface)); } bool Codec2Client::IsAidlSelected() { return c2_aidl::utils::IsSelected(); } Loading Loading @@ -3674,92 +3672,6 @@ void Codec2Client::Component::holdIgbaBlocks( } } c2_status_t Codec2Client::Component::connectToInputSurface( const std::shared_ptr<InputSurface>& inputSurface, std::shared_ptr<InputSurfaceConnection>* connection) { if (mApexBase) { // FIXME return C2_OMITTED; } if (mAidlBase) { // FIXME return C2_OMITTED; } c2_status_t status; Return<void> transStatus = mHidlBase1_0->connectToInputSurface( inputSurface->mBase, [&status, connection]( c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) { status = static_cast<c2_status_t>(s); if (status != C2_OK) { LOG(DEBUG) << "connectToInputSurface -- call failed: " << status << "."; return; } *connection = std::make_shared<InputSurfaceConnection>(c); }); if (!transStatus.isOk()) { LOG(ERROR) << "connectToInputSurface -- transaction failed"; return C2_TRANSACTION_FAILED; } return status; } c2_status_t Codec2Client::Component::connectToOmxInputSurface( const sp<HGraphicBufferProducer1>& producer, const sp<HGraphicBufferSource>& source, std::shared_ptr<InputSurfaceConnection>* connection) { if (mApexBase) { LOG(WARNING) << "Connecting to OMX input surface is not supported for AIDL C2 HAL"; return C2_OMITTED; } if (mAidlBase) { LOG(WARNING) << "Connecting to OMX input surface is not supported for AIDL C2 HAL"; return C2_OMITTED; } c2_status_t status; Return<void> transStatus = mHidlBase1_0->connectToOmxInputSurface( producer, source, [&status, connection]( c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) { status = static_cast<c2_status_t>(s); if (status != C2_OK) { LOG(DEBUG) << "connectToOmxInputSurface -- call failed: " << status << "."; return; } *connection = std::make_shared<InputSurfaceConnection>(c); }); if (!transStatus.isOk()) { LOG(ERROR) << "connectToOmxInputSurface -- transaction failed."; return C2_TRANSACTION_FAILED; } return status; } c2_status_t Codec2Client::Component::disconnectFromInputSurface() { if (mApexBase) { // FIXME return C2_OMITTED; } if (mAidlBase) { // FIXME return C2_OMITTED; } Return<c2_hidl::Status> transStatus = mHidlBase1_0->disconnectFromInputSurface(); if (!transStatus.isOk()) { LOG(ERROR) << "disconnectToInputSurface -- transaction failed."; return C2_TRANSACTION_FAILED; } c2_status_t status = static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); if (status != C2_OK) { LOG(DEBUG) << "disconnectFromInputSurface -- call failed: " << status << "."; } return status; } Codec2Client::Component::AidlDeathManager *Codec2Client::Component::GetAidlDeathManager() { // This object never gets destructed static AidlDeathManager *sManager = new AidlDeathManager(); Loading Loading @@ -3823,54 +3735,90 @@ c2_status_t Codec2Client::Component::setDeathListener( } // Codec2Client::InputSurface Codec2Client::InputSurface::InputSurface(const sp<c2_hidl::IInputSurface>& base) Codec2Client::InputSurface::InputSurface(const std::shared_ptr<c2_aidl::IInputSurface>& base) : Configurable{ [base]() -> sp<c2_hidl::IConfigurable> { Return<sp<c2_hidl::IConfigurable>> transResult = base->getConfigurable(); return transResult.isOk() ? static_cast<sp<c2_hidl::IConfigurable>>(transResult) : nullptr; [base]() -> std::shared_ptr<c2_aidl::IConfigurable> { std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable; ::ndk::ScopedAStatus transStatus = base->getConfigurable(&aidlConfigurable); return transStatus.isOk() ? aidlConfigurable : nullptr; }() }, mBase{base}, mGraphicBufferProducer{new H2BGraphicBufferProducer2([base]() -> sp<HGraphicBufferProducer2> { Return<sp<HGraphicBufferProducer2>> transResult = base->getGraphicBufferProducer(); return transResult.isOk() ? static_cast<sp<HGraphicBufferProducer2>>(transResult) : nullptr; }())} { mBase{base}, mNativeWindow{nullptr} { } sp<IGraphicBufferProducer> Codec2Client::InputSurface::getGraphicBufferProducer() const { return mGraphicBufferProducer; ANativeWindow *Codec2Client::InputSurface::getNativeWindow() { std::call_once(mWindowInitOnce, [this]() { ::aidl::android::view::Surface surface; ::ndk::ScopedAStatus transStatus = mBase->getSurface(&surface); c2_status_t c2Status = GetC2Status(transStatus, "InputSurface::getNativeWindow"); if (c2Status != C2_OK) { LOG(ERROR) << "InputSurface::getNativeWindow -- cannot get window: " << c2Status; return; } mNativeWindow = surface.release(); }); return mNativeWindow; } sp<c2_hidl::IInputSurface> Codec2Client::InputSurface::getHalInterface() const { return mBase; ::ndk::SpAIBinder Codec2Client::InputSurface::getHalInterface() const { return mBase ? mBase->asBinder() : nullptr; } c2_status_t Codec2Client::InputSurface::connect( const std::shared_ptr<Codec2Client::Component> &comp, std::shared_ptr<Connection> *connection) { if (!comp) { LOG(ERROR) << "InputSurface:connect, component invalid"; return C2_BAD_VALUE; } std::shared_ptr<Codec2Client::Component::AidlBase> aidlBase = comp->mAidlBase; if (!aidlBase) { LOG(ERROR) << "InputSurface:connect, component invalid"; return C2_BAD_VALUE; } std::shared_ptr<c2_aidl::IInputSink> sink; ::ndk::ScopedAStatus transResult = aidlBase->asInputSink(&sink); if (GetC2Status(transResult, "InputSurface:Component:asInputSink") != C2_OK) { LOG(ERROR) << "InputSurface:connect sink conversion failed"; return C2_CORRUPTED; } if (!mBase) { LOG(ERROR) << "InputSurface:connect failed, no valid base"; return C2_CORRUPTED; } std::shared_ptr<ConnectionBase> base; transResult = mBase->connect(sink, &base); c2_status_t c2Status = GetC2Status(transResult, "InputSurface:connect"); if (c2Status != C2_OK) { LOG(ERROR) << "IInputSurface:connect failed: " << c2Status; return c2Status; } *connection = std::make_shared<Connection>(base); return C2_OK; } // Codec2Client::InputSurfaceConnection Codec2Client::InputSurfaceConnection::InputSurfaceConnection( const sp<c2_hidl::IInputSurfaceConnection>& base) : Configurable{ [base]() -> sp<c2_hidl::IConfigurable> { Return<sp<c2_hidl::IConfigurable>> transResult = base->getConfigurable(); return transResult.isOk() ? static_cast<sp<c2_hidl::IConfigurable>>(transResult) : nullptr; }() }, mBase{base} { const std::shared_ptr<c2_aidl::IInputSurfaceConnection>& base) : mBase{base} { } c2_status_t Codec2Client::InputSurfaceConnection::disconnect() { Return<c2_hidl::Status> transResult = mBase->disconnect(); return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult)); if (!mBase) { LOG(ERROR) << "InputSurfaceConnection:disconnect failed, no valid base"; return C2_CORRUPTED; } ::ndk::ScopedAStatus transResult = mBase->disconnect(); return GetC2Status(transResult, "InputSurfaceConnection::disconnect"); } c2_status_t Codec2Client::InputSurfaceConnection::signalEos() { if (!mBase) { LOG(ERROR) << "InputSurfaceConnection:signalEos failed, no valid base"; return C2_CORRUPTED; } ::ndk::ScopedAStatus transResult = mBase->signalEndOfStream(); return GetC2Status(transResult, "InputSurfaceConnection::signalEndOfStream"); } } // namespace android media/codec2/hal/client/include/codec2/hidl/client.h +57 −29 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <C2Param.h> #include <C2.h> #include <android/native_window_aidl.h> #include <gui/FrameTimestamps.h> #include <gui/IGraphicBufferProducer.h> #include <hidl/HidlSupport.h> Loading Loading @@ -69,9 +70,6 @@ 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::c2::V1_1 { Loading @@ -89,6 +87,9 @@ class IComponent; class IComponentInterface; class IComponentStore; class IConfigurable; class IInputSink; class IInputSurface; class IInputSurfaceConnection; } // namespace aidl::android::hardware::media::c2 namespace android::hardware::media::bufferpool::V2_0 { Loading Loading @@ -190,6 +191,7 @@ struct Codec2Client : public Codec2ConfigurableClient { typedef HidlBase1_0 HidlBase; typedef ::aidl::android::hardware::media::c2::IComponentStore AidlBase; typedef ::aidl::android::hardware::media::c2::IInputSurface IInputSurface; struct Listener; Loading Loading @@ -276,6 +278,10 @@ struct Codec2Client : public Codec2ConfigurableClient { static std::shared_ptr<InputSurface> CreateInputSurface( char const* serviceName = nullptr); // Create an input surface from an existing interface. static std::shared_ptr<InputSurface> CreateInputSurfaceFromInterface( const ::ndk::SpAIBinder &interface); // Whether AIDL is selected. static bool IsAidlSelected(); Loading Loading @@ -523,18 +529,6 @@ struct Codec2Client::Component : public Codec2Client::Configurable { void holdIgbaBlocks( const std::list<std::unique_ptr<C2Work>>& workList); // 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(); c2_status_t initApexHandler( const std::shared_ptr<Listener> &listener, const std::shared_ptr<Component> &comp); Loading Loading @@ -595,44 +589,78 @@ protected: void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems); }; // Creation of InputSurface // Codec2Client --> Codec2Client::InputSurface. // Codec2Client::InputSurface --> Codec2Client::InputSurfaceConnection // // Codec2Client::InputSurface could have at most only one // Codec2Client::InputSurfaceConnection at any given time. // // A Codec2Client::InputSurfaceConnection is valid during a video encoder // session. After a encoder session, the end of stream can be notified by // Codec2Client::InputSurfaceConnection::signalEos() to the encoder. // // Codec2Client::InputSurfaceConnection::disconnect() will disconnect from the // encoder and notify that it is no longer valid to Codec2Client::InputSurface. // On disconnect() Codec2Client::InputSurface will perform clean-up, then // Codec2Client::InputSurface is ready to re-start with a new encoder and a new // Codec2Client::InputSurfaceConnection. // The class holds ::aidl::android::hardware::media::c2::IInputSurface for the // client framework. 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 ::aidl::android::hardware::media::c2::IInputSurface Base; typedef Codec2Client::InputSurfaceConnection Connection; typedef ::aidl::android::hardware::media::c2::IInputSurfaceConnection ConnectionBase; typedef ::android::IGraphicBufferProducer IGraphicBufferProducer; typedef Codec2Client::InputSurfaceConnection Connection; sp<IGraphicBufferProducer> getGraphicBufferProducer() const; // Return the window which is owned by the underlying interface. ANativeWindow *getNativeWindow(); // Return the underlying IInputSurface. sp<Base> getHalInterface() const; ::ndk::SpAIBinder getHalInterface() const; // connect to a video encoder component. c2_status_t connect( const std::shared_ptr<Codec2Client::Component> &comp, std::shared_ptr<Connection> *connection); // base cannot be null. InputSurface(const sp<Base>& base); InputSurface(const std::shared_ptr<Base>& base); protected: sp<Base> mBase; sp<IGraphicBufferProducer> mGraphicBufferProducer; std::shared_ptr<Base> mBase; std::once_flag mWindowInitOnce; ANativeWindow *mNativeWindow; // lazily initialized, // for later construction params binding. friend struct Codec2Client; friend struct Component; }; struct Codec2Client::InputSurfaceConnection : public Codec2Client::Configurable { // The class holds ::aidl::android::hardware::media::c2::IInputSurfaceConnection // for the client framework. struct Codec2Client::InputSurfaceConnection { typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection Base; typedef ::aidl::android::hardware::media::c2::IInputSurfaceConnection Base; // disconnect from a video encoder from the class. // This will eventually notify Codec2Client::InputSurface that // life cycle of the class is ended. c2_status_t disconnect(); // signal Eos to the connected video encoder. c2_status_t signalEos(); // base cannot be null. InputSurfaceConnection(const sp<Base>& base); InputSurfaceConnection(const std::shared_ptr<Base>& base); protected: sp<Base> mBase; std::shared_ptr<Base> mBase; friend struct Codec2Client::InputSurface; }; Loading Loading
media/codec2/hal/client/client.cpp +89 −141 Original line number Diff line number Diff line Loading @@ -2281,30 +2281,22 @@ c2_status_t Codec2Client::createInputSurface( // Not supported for APEX. return C2_OMITTED; } if (mAidlBase) { // FIXME if (!mAidlBase) { // Only AIDL supports InputSurface. return C2_OMITTED; } c2_status_t status; Return<void> transStatus = mHidlBase1_0->createInputSurface( [&status, inputSurface]( c2_hidl::Status s, const sp<c2_hidl::IInputSurface>& i) { status = static_cast<c2_status_t>(s); if (status != C2_OK) { return; if (!IsCodec2AidlInputSurfaceSelected()) { return C2_OMITTED; } *inputSurface = std::make_shared<InputSurface>(i); }); if (!transStatus.isOk()) { LOG(ERROR) << "createInputSurface -- transaction failed."; return C2_TRANSACTION_FAILED; } else if (status != C2_OK) { LOG(DEBUG) << "createInputSurface -- call failed: " << status << "."; std::shared_ptr<c2_aidl::IInputSurface> interface; ndk::ScopedAStatus status = mAidlBase->createInputSurface(&interface); c2_status_t c2Status = GetC2Status(status, "createInputSurface"); if (c2Status != C2_OK) { LOG(ERROR) << "createInputSurface() failed: " << c2Status; return c2Status; } return status; *inputSurface = std::make_shared<InputSurface>(interface); return C2_OK; } std::vector<C2Component::Traits> const& Codec2Client::listComponents() const { Loading Loading @@ -2823,6 +2815,12 @@ std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurface( return nullptr; } std::shared_ptr<Codec2Client::InputSurface> Codec2Client::CreateInputSurfaceFromInterface( const ::ndk::SpAIBinder &interface) { return std::make_shared<Codec2Client::InputSurface>( c2_aidl::IInputSurface::fromBinder(interface)); } bool Codec2Client::IsAidlSelected() { return c2_aidl::utils::IsSelected(); } Loading Loading @@ -3674,92 +3672,6 @@ void Codec2Client::Component::holdIgbaBlocks( } } c2_status_t Codec2Client::Component::connectToInputSurface( const std::shared_ptr<InputSurface>& inputSurface, std::shared_ptr<InputSurfaceConnection>* connection) { if (mApexBase) { // FIXME return C2_OMITTED; } if (mAidlBase) { // FIXME return C2_OMITTED; } c2_status_t status; Return<void> transStatus = mHidlBase1_0->connectToInputSurface( inputSurface->mBase, [&status, connection]( c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) { status = static_cast<c2_status_t>(s); if (status != C2_OK) { LOG(DEBUG) << "connectToInputSurface -- call failed: " << status << "."; return; } *connection = std::make_shared<InputSurfaceConnection>(c); }); if (!transStatus.isOk()) { LOG(ERROR) << "connectToInputSurface -- transaction failed"; return C2_TRANSACTION_FAILED; } return status; } c2_status_t Codec2Client::Component::connectToOmxInputSurface( const sp<HGraphicBufferProducer1>& producer, const sp<HGraphicBufferSource>& source, std::shared_ptr<InputSurfaceConnection>* connection) { if (mApexBase) { LOG(WARNING) << "Connecting to OMX input surface is not supported for AIDL C2 HAL"; return C2_OMITTED; } if (mAidlBase) { LOG(WARNING) << "Connecting to OMX input surface is not supported for AIDL C2 HAL"; return C2_OMITTED; } c2_status_t status; Return<void> transStatus = mHidlBase1_0->connectToOmxInputSurface( producer, source, [&status, connection]( c2_hidl::Status s, const sp<c2_hidl::IInputSurfaceConnection>& c) { status = static_cast<c2_status_t>(s); if (status != C2_OK) { LOG(DEBUG) << "connectToOmxInputSurface -- call failed: " << status << "."; return; } *connection = std::make_shared<InputSurfaceConnection>(c); }); if (!transStatus.isOk()) { LOG(ERROR) << "connectToOmxInputSurface -- transaction failed."; return C2_TRANSACTION_FAILED; } return status; } c2_status_t Codec2Client::Component::disconnectFromInputSurface() { if (mApexBase) { // FIXME return C2_OMITTED; } if (mAidlBase) { // FIXME return C2_OMITTED; } Return<c2_hidl::Status> transStatus = mHidlBase1_0->disconnectFromInputSurface(); if (!transStatus.isOk()) { LOG(ERROR) << "disconnectToInputSurface -- transaction failed."; return C2_TRANSACTION_FAILED; } c2_status_t status = static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transStatus)); if (status != C2_OK) { LOG(DEBUG) << "disconnectFromInputSurface -- call failed: " << status << "."; } return status; } Codec2Client::Component::AidlDeathManager *Codec2Client::Component::GetAidlDeathManager() { // This object never gets destructed static AidlDeathManager *sManager = new AidlDeathManager(); Loading Loading @@ -3823,54 +3735,90 @@ c2_status_t Codec2Client::Component::setDeathListener( } // Codec2Client::InputSurface Codec2Client::InputSurface::InputSurface(const sp<c2_hidl::IInputSurface>& base) Codec2Client::InputSurface::InputSurface(const std::shared_ptr<c2_aidl::IInputSurface>& base) : Configurable{ [base]() -> sp<c2_hidl::IConfigurable> { Return<sp<c2_hidl::IConfigurable>> transResult = base->getConfigurable(); return transResult.isOk() ? static_cast<sp<c2_hidl::IConfigurable>>(transResult) : nullptr; [base]() -> std::shared_ptr<c2_aidl::IConfigurable> { std::shared_ptr<c2_aidl::IConfigurable> aidlConfigurable; ::ndk::ScopedAStatus transStatus = base->getConfigurable(&aidlConfigurable); return transStatus.isOk() ? aidlConfigurable : nullptr; }() }, mBase{base}, mGraphicBufferProducer{new H2BGraphicBufferProducer2([base]() -> sp<HGraphicBufferProducer2> { Return<sp<HGraphicBufferProducer2>> transResult = base->getGraphicBufferProducer(); return transResult.isOk() ? static_cast<sp<HGraphicBufferProducer2>>(transResult) : nullptr; }())} { mBase{base}, mNativeWindow{nullptr} { } sp<IGraphicBufferProducer> Codec2Client::InputSurface::getGraphicBufferProducer() const { return mGraphicBufferProducer; ANativeWindow *Codec2Client::InputSurface::getNativeWindow() { std::call_once(mWindowInitOnce, [this]() { ::aidl::android::view::Surface surface; ::ndk::ScopedAStatus transStatus = mBase->getSurface(&surface); c2_status_t c2Status = GetC2Status(transStatus, "InputSurface::getNativeWindow"); if (c2Status != C2_OK) { LOG(ERROR) << "InputSurface::getNativeWindow -- cannot get window: " << c2Status; return; } mNativeWindow = surface.release(); }); return mNativeWindow; } sp<c2_hidl::IInputSurface> Codec2Client::InputSurface::getHalInterface() const { return mBase; ::ndk::SpAIBinder Codec2Client::InputSurface::getHalInterface() const { return mBase ? mBase->asBinder() : nullptr; } c2_status_t Codec2Client::InputSurface::connect( const std::shared_ptr<Codec2Client::Component> &comp, std::shared_ptr<Connection> *connection) { if (!comp) { LOG(ERROR) << "InputSurface:connect, component invalid"; return C2_BAD_VALUE; } std::shared_ptr<Codec2Client::Component::AidlBase> aidlBase = comp->mAidlBase; if (!aidlBase) { LOG(ERROR) << "InputSurface:connect, component invalid"; return C2_BAD_VALUE; } std::shared_ptr<c2_aidl::IInputSink> sink; ::ndk::ScopedAStatus transResult = aidlBase->asInputSink(&sink); if (GetC2Status(transResult, "InputSurface:Component:asInputSink") != C2_OK) { LOG(ERROR) << "InputSurface:connect sink conversion failed"; return C2_CORRUPTED; } if (!mBase) { LOG(ERROR) << "InputSurface:connect failed, no valid base"; return C2_CORRUPTED; } std::shared_ptr<ConnectionBase> base; transResult = mBase->connect(sink, &base); c2_status_t c2Status = GetC2Status(transResult, "InputSurface:connect"); if (c2Status != C2_OK) { LOG(ERROR) << "IInputSurface:connect failed: " << c2Status; return c2Status; } *connection = std::make_shared<Connection>(base); return C2_OK; } // Codec2Client::InputSurfaceConnection Codec2Client::InputSurfaceConnection::InputSurfaceConnection( const sp<c2_hidl::IInputSurfaceConnection>& base) : Configurable{ [base]() -> sp<c2_hidl::IConfigurable> { Return<sp<c2_hidl::IConfigurable>> transResult = base->getConfigurable(); return transResult.isOk() ? static_cast<sp<c2_hidl::IConfigurable>>(transResult) : nullptr; }() }, mBase{base} { const std::shared_ptr<c2_aidl::IInputSurfaceConnection>& base) : mBase{base} { } c2_status_t Codec2Client::InputSurfaceConnection::disconnect() { Return<c2_hidl::Status> transResult = mBase->disconnect(); return static_cast<c2_status_t>(static_cast<c2_hidl::Status>(transResult)); if (!mBase) { LOG(ERROR) << "InputSurfaceConnection:disconnect failed, no valid base"; return C2_CORRUPTED; } ::ndk::ScopedAStatus transResult = mBase->disconnect(); return GetC2Status(transResult, "InputSurfaceConnection::disconnect"); } c2_status_t Codec2Client::InputSurfaceConnection::signalEos() { if (!mBase) { LOG(ERROR) << "InputSurfaceConnection:signalEos failed, no valid base"; return C2_CORRUPTED; } ::ndk::ScopedAStatus transResult = mBase->signalEndOfStream(); return GetC2Status(transResult, "InputSurfaceConnection::signalEndOfStream"); } } // namespace android
media/codec2/hal/client/include/codec2/hidl/client.h +57 −29 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <C2Param.h> #include <C2.h> #include <android/native_window_aidl.h> #include <gui/FrameTimestamps.h> #include <gui/IGraphicBufferProducer.h> #include <hidl/HidlSupport.h> Loading Loading @@ -69,9 +70,6 @@ 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::c2::V1_1 { Loading @@ -89,6 +87,9 @@ class IComponent; class IComponentInterface; class IComponentStore; class IConfigurable; class IInputSink; class IInputSurface; class IInputSurfaceConnection; } // namespace aidl::android::hardware::media::c2 namespace android::hardware::media::bufferpool::V2_0 { Loading Loading @@ -190,6 +191,7 @@ struct Codec2Client : public Codec2ConfigurableClient { typedef HidlBase1_0 HidlBase; typedef ::aidl::android::hardware::media::c2::IComponentStore AidlBase; typedef ::aidl::android::hardware::media::c2::IInputSurface IInputSurface; struct Listener; Loading Loading @@ -276,6 +278,10 @@ struct Codec2Client : public Codec2ConfigurableClient { static std::shared_ptr<InputSurface> CreateInputSurface( char const* serviceName = nullptr); // Create an input surface from an existing interface. static std::shared_ptr<InputSurface> CreateInputSurfaceFromInterface( const ::ndk::SpAIBinder &interface); // Whether AIDL is selected. static bool IsAidlSelected(); Loading Loading @@ -523,18 +529,6 @@ struct Codec2Client::Component : public Codec2Client::Configurable { void holdIgbaBlocks( const std::list<std::unique_ptr<C2Work>>& workList); // 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(); c2_status_t initApexHandler( const std::shared_ptr<Listener> &listener, const std::shared_ptr<Component> &comp); Loading Loading @@ -595,44 +589,78 @@ protected: void handleOnWorkDone(const std::list<std::unique_ptr<C2Work>> &workItems); }; // Creation of InputSurface // Codec2Client --> Codec2Client::InputSurface. // Codec2Client::InputSurface --> Codec2Client::InputSurfaceConnection // // Codec2Client::InputSurface could have at most only one // Codec2Client::InputSurfaceConnection at any given time. // // A Codec2Client::InputSurfaceConnection is valid during a video encoder // session. After a encoder session, the end of stream can be notified by // Codec2Client::InputSurfaceConnection::signalEos() to the encoder. // // Codec2Client::InputSurfaceConnection::disconnect() will disconnect from the // encoder and notify that it is no longer valid to Codec2Client::InputSurface. // On disconnect() Codec2Client::InputSurface will perform clean-up, then // Codec2Client::InputSurface is ready to re-start with a new encoder and a new // Codec2Client::InputSurfaceConnection. // The class holds ::aidl::android::hardware::media::c2::IInputSurface for the // client framework. 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 ::aidl::android::hardware::media::c2::IInputSurface Base; typedef Codec2Client::InputSurfaceConnection Connection; typedef ::aidl::android::hardware::media::c2::IInputSurfaceConnection ConnectionBase; typedef ::android::IGraphicBufferProducer IGraphicBufferProducer; typedef Codec2Client::InputSurfaceConnection Connection; sp<IGraphicBufferProducer> getGraphicBufferProducer() const; // Return the window which is owned by the underlying interface. ANativeWindow *getNativeWindow(); // Return the underlying IInputSurface. sp<Base> getHalInterface() const; ::ndk::SpAIBinder getHalInterface() const; // connect to a video encoder component. c2_status_t connect( const std::shared_ptr<Codec2Client::Component> &comp, std::shared_ptr<Connection> *connection); // base cannot be null. InputSurface(const sp<Base>& base); InputSurface(const std::shared_ptr<Base>& base); protected: sp<Base> mBase; sp<IGraphicBufferProducer> mGraphicBufferProducer; std::shared_ptr<Base> mBase; std::once_flag mWindowInitOnce; ANativeWindow *mNativeWindow; // lazily initialized, // for later construction params binding. friend struct Codec2Client; friend struct Component; }; struct Codec2Client::InputSurfaceConnection : public Codec2Client::Configurable { // The class holds ::aidl::android::hardware::media::c2::IInputSurfaceConnection // for the client framework. struct Codec2Client::InputSurfaceConnection { typedef ::android::hardware::media::c2::V1_0::IInputSurfaceConnection Base; typedef ::aidl::android::hardware::media::c2::IInputSurfaceConnection Base; // disconnect from a video encoder from the class. // This will eventually notify Codec2Client::InputSurface that // life cycle of the class is ended. c2_status_t disconnect(); // signal Eos to the connected video encoder. c2_status_t signalEos(); // base cannot be null. InputSurfaceConnection(const sp<Base>& base); InputSurfaceConnection(const std::shared_ptr<Base>& base); protected: sp<Base> mBase; std::shared_ptr<Base> mBase; friend struct Codec2Client::InputSurface; }; Loading