Loading media/libstagefright/codec2/hidl/impl/1.0/Android.bp 0 → 100644 +42 −0 Original line number Diff line number Diff line cc_library { name: "libstagefright_codec2_hidl@1.0", vendor_available: true, vndk: { enabled: true, }, defaults: ["hidl_defaults"], srcs: [ "Component.cpp", "ComponentStore.cpp", "Configurable.cpp", "types.cpp", ], shared_libs: [ "android.hardware.media.bufferpool@1.0", "libcutils", "libhidlbase", "libhidltransport", "liblog", "libstagefright_codec2", "libstagefright_codec2_vndk", "libutils", "vendor.google.media.c2@1.0", ], export_include_dirs: [ "include", ], export_shared_lib_headers: [ "libstagefright_codec2", ], // Private include directories header_libs: [ "libstagefright_codec2_internal", ], } media/libstagefright/codec2/hidl/impl/1.0/Component.cpp 0 → 100644 +245 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "Codec2-Component" #include <log/log.h> #include <codec2/hidl/1.0/Component.h> #include <codec2/hidl/1.0/types.h> namespace vendor { namespace google { namespace media { namespace c2 { namespace V1_0 { namespace implementation { using namespace ::android; // Implementation of ConfigurableC2Intf based on C2ComponentInterface struct CompIntf : public ConfigurableC2Intf { CompIntf(const std::shared_ptr<C2ComponentInterface>& intf) : ConfigurableC2Intf(intf->getName()), mIntf(intf) { } virtual c2_status_t config( const std::vector<C2Param*>& params, c2_blocking_t mayBlock, std::vector<std::unique_ptr<C2SettingResult>>* const failures ) override { return mIntf->config_vb(params, mayBlock, failures); } virtual c2_status_t query( const std::vector<C2Param::Index>& indices, c2_blocking_t mayBlock, std::vector<std::unique_ptr<C2Param>>* const params) override { return mIntf->query_vb({}, indices, mayBlock, params); } virtual c2_status_t querySupportedParams( std::vector<std::shared_ptr<C2ParamDescriptor>>* const params ) const override { return mIntf->querySupportedParams_nb(params); } virtual c2_status_t querySupportedValues( std::vector<C2FieldSupportedValuesQuery>& fields, c2_blocking_t mayBlock) const override { return mIntf->querySupportedValues_vb(fields, mayBlock); } protected: std::shared_ptr<C2ComponentInterface> mIntf; }; // ComponentInterface ComponentInterface::ComponentInterface( const std::shared_ptr<C2ComponentInterface>& intf, const sp<ComponentStore>& store) : Configurable(new CachedConfigurable(std::make_unique<CompIntf>(intf))), mInterface(intf) { mInit = init(store.get()); } c2_status_t ComponentInterface::status() const { return mInit; } // ComponentListener wrapper struct Listener : public C2Component::Listener { Listener(const wp<IComponentListener>& listener) : mListener(listener) { // TODO: Should we track interface errors? We could reuse onError() or // create our own error channel. } virtual void onError_nb( std::weak_ptr<C2Component> /* c2component */, uint32_t errorCode) override { sp<IComponentListener> listener = mListener.promote(); if (listener) { listener->onError(Status::OK, errorCode); } } virtual void onTripped_nb( std::weak_ptr<C2Component> /* c2component */, std::vector<std::shared_ptr<C2SettingResult>> c2settingResult ) override { sp<IComponentListener> listener = mListener.promote(); if (listener) { hidl_vec<SettingResult> settingResults(c2settingResult.size()); size_t ix = 0; for (const std::shared_ptr<C2SettingResult> &c2result : c2settingResult) { if (c2result) { objcpy(&settingResults[ix++], *c2result); } } settingResults.resize(ix); listener->onTripped(settingResults); } } virtual void onWorkDone_nb( std::weak_ptr<C2Component> /* c2component */, std::list<std::unique_ptr<C2Work>> c2workItems) override { sp<IComponentListener> listener = mListener.promote(); if (listener) { WorkBundle workBundle; // TODO: Connect with bufferpool API to send Works & Buffers if (objcpy(&workBundle, c2workItems) != Status::OK) { ALOGE("onWorkDone() received corrupted work items."); return; } listener->onWorkDone(workBundle); // Finish buffer transfers: nothing else to do } } protected: wp<IComponentListener> mListener; }; // Component Component::Component( const std::shared_ptr<C2Component>& component, const sp<IComponentListener>& listener, const sp<ComponentStore>& store) : Configurable(new CachedConfigurable( std::make_unique<CompIntf>(component->intf()))), mComponent(component), mInterface(component->intf()), mListener(listener) /* , // TODO: Do we need store for anything? mStore(store)*/ { std::shared_ptr<C2Component::Listener> c2listener = std::make_shared<Listener>(listener); c2_status_t res = mComponent->setListener_vb(c2listener, C2_DONT_BLOCK); // Retrieve supported parameters from store // TODO: We could cache this per component/interface type mInit = init(store.get()); mInit = mInit != C2_OK ? res : mInit; } // Methods from ::android::hardware::media::c2::V1_0::IComponent Return<Status> Component::queue(const WorkBundle& workBundle) { std::list<std::unique_ptr<C2Work>> c2works; // TODO: Connect with bufferpool API for buffer transfers if (objcpy(&c2works, workBundle) != C2_OK) { return Status::CORRUPTED; } (void)workBundle; return static_cast<Status>(mComponent->queue_nb(&c2works)); } Return<void> Component::flush(flush_cb _hidl_cb) { std::list<std::unique_ptr<C2Work>> c2flushedWorks; c2_status_t c2res = mComponent->flush_sm( C2Component::FLUSH_COMPONENT, &c2flushedWorks); WorkBundle flushedWorkBundle; Status res = static_cast<Status>(c2res); if (c2res == C2_OK) { // TODO: Connect with bufferpool API for buffer transfers res = objcpy(&flushedWorkBundle, c2flushedWorks); } _hidl_cb(res, flushedWorkBundle); return Void(); } Return<Status> Component::drain(bool withEos) { return static_cast<Status>(mComponent->drain_nb(withEos ? C2Component::DRAIN_COMPONENT_WITH_EOS : C2Component::DRAIN_COMPONENT_NO_EOS)); } Return<Status> Component::connectToInputSurface(const sp<IInputSurface>& surface) { // TODO implement (void)surface; return Status::OK; } Return<Status> Component::connectToOmxInputSurface( const sp<::android::hardware::graphics::bufferqueue::V1_0:: IGraphicBufferProducer>& producer, const sp<::android::hardware::media::omx::V1_0:: IGraphicBufferSource>& source) { // TODO implement (void)producer; (void)source; return Status::OK; } Return<Status> Component::disconnectFromInputSurface() { // TODO implement return Status::OK; } Return<void> Component::createBlockPool(uint32_t allocatorId, createBlockPool_cb _hidl_cb) { // TODO implement (void)allocatorId; _hidl_cb(Status::OK, 0 /* blockPoolId */, nullptr /* configurable */); return Void(); } Return<Status> Component::start() { return static_cast<Status>(mComponent->start()); } Return<Status> Component::stop() { return static_cast<Status>(mComponent->stop()); } Return<Status> Component::reset() { return static_cast<Status>(mComponent->reset()); } Return<Status> Component::release() { return static_cast<Status>(mComponent->release()); } } // namespace implementation } // namespace V1_0 } // namespace c2 } // namespace media } // namespace google } // namespace vendor media/libstagefright/codec2/hidl/impl/1.0/ComponentStore.cpp 0 → 100644 +212 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "Codec2-ComponentStore" #include <log/log.h> #include <codec2/hidl/1.0/ComponentStore.h> #include <codec2/hidl/1.0/Component.h> #include <codec2/hidl/1.0/ConfigurableC2Intf.h> #include <codec2/hidl/1.0/types.h> namespace vendor { namespace google { namespace media { namespace c2 { namespace V1_0 { namespace implementation { using namespace ::android; struct StoreIntf : public ConfigurableC2Intf { StoreIntf(const std::shared_ptr<C2ComponentStore>& store) : ConfigurableC2Intf(store ? store->getName() : ""), mStore(store) { } c2_status_t config( const std::vector<C2Param*> ¶ms, c2_blocking_t mayBlock, std::vector<std::unique_ptr<C2SettingResult>> *const failures ) override { // Assume all params are blocking // TODO: Filter for supported params if (mayBlock == C2_DONT_BLOCK && params.size() != 0) { return C2_BLOCKING; } return mStore->config_sm(params, failures); } c2_status_t query( const std::vector<C2Param::Index> &indices, c2_blocking_t mayBlock, std::vector<std::unique_ptr<C2Param>> *const params) override { // Assume all params are blocking // TODO: Filter for supported params if (mayBlock == C2_DONT_BLOCK && indices.size() != 0) { return C2_BLOCKING; } return mStore->query_sm({}, indices, params); } c2_status_t querySupportedParams( std::vector<std::shared_ptr<C2ParamDescriptor>> *const params ) const override { return mStore->querySupportedParams_nb(params); } c2_status_t querySupportedValues( std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const override { // Assume all params are blocking // TODO: Filter for supported params if (mayBlock == C2_DONT_BLOCK && fields.size() != 0) { return C2_BLOCKING; } return mStore->querySupportedValues_sm(fields); } protected: std::shared_ptr<C2ComponentStore> mStore; }; ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store) : Configurable(new CachedConfigurable(std::make_unique<StoreIntf>(store))), mStore(store) { // Retrieve struct descriptors mParamReflector = mStore->getParamReflector(); // Retrieve supported parameters from store mInit = init(this); } c2_status_t ComponentStore::validateSupportedParams( const std::vector<std::shared_ptr<C2ParamDescriptor>>& params) { c2_status_t res = C2_OK; for (const std::shared_ptr<C2ParamDescriptor> &desc : params) { if (!desc) { // All descriptors should be valid res = res ? res : C2_BAD_VALUE; continue; } C2Param::CoreIndex coreIndex = desc->index().coreIndex(); auto it = mStructDescriptors.find(coreIndex); if (it == mStructDescriptors.end()) { std::shared_ptr<C2StructDescriptor> structDesc = mParamReflector->describe(coreIndex); if (!structDesc) { // All supported params must be described res = C2_BAD_INDEX; } mStructDescriptors.insert({ coreIndex, structDesc }); } } return res; } // Methods from ::android::hardware::media::c2::V1_0::IComponentStore Return<void> ComponentStore::createComponent( const hidl_string& name, const sp<IComponentListener>& listener, // TODO: Return the pool if the component has it. const sp<IClientManager>& /* pool */, createComponent_cb _hidl_cb) { std::shared_ptr<C2Component> c2component; c2_status_t res = mStore->createComponent(name, &c2component); sp<IComponent> component; if (res == C2_OK) { component = new Component(c2component, listener, this); } _hidl_cb((Status)res, component); return Void(); } Return<void> ComponentStore::createInterface( const hidl_string& name, createInterface_cb _hidl_cb) { std::shared_ptr<C2ComponentInterface> c2interface; c2_status_t res = mStore->createInterface(name, &c2interface); sp<IComponentInterface> interface; if (res == C2_OK) { interface = new ComponentInterface(c2interface, this); } _hidl_cb((Status)res, interface); return Void(); } Return<void> ComponentStore::listComponents(listComponents_cb _hidl_cb) { std::vector<std::shared_ptr<const C2Component::Traits>> c2traits = mStore->listComponents(); hidl_vec<IComponentStore::ComponentTraits> traits(c2traits.size()); size_t ix = 0; for (const std::shared_ptr<const C2Component::Traits> &c2trait : c2traits) { if (c2trait) { objcpy(&traits[ix++], *c2trait); } } traits.resize(ix); _hidl_cb(traits); return Void(); } Return<sp<IInputSurface>> ComponentStore::createInputSurface() { // TODO implement return sp<IInputSurface> {}; } Return<void> ComponentStore::getStructDescriptors( const hidl_vec<uint32_t>& indices, getStructDescriptors_cb _hidl_cb) { hidl_vec<StructDescriptor> descriptors(indices.size()); size_t dstIx = 0; Status res; for (size_t srcIx = 0; srcIx < indices.size(); ++srcIx) { const auto item = mStructDescriptors.find( C2Param::CoreIndex(indices[srcIx]).coreIndex()); if (item == mStructDescriptors.end()) { res = Status::NOT_FOUND; } else if (item->second) { objcpy(&descriptors[dstIx++], *item->second); } else { res = Status::NO_MEMORY; } } descriptors.resize(dstIx); _hidl_cb(res, descriptors); return Void(); } Return<sp<IClientManager>> ComponentStore::getPoolClientManager() { // TODO implement return sp<IClientManager> {}; } Return<Status> ComponentStore::copyBuffer(const Buffer& src, const Buffer& dst) { // TODO implement (void)src; (void)dst; return Status {}; } } // namespace implementation } // namespace V1_0 } // namespace c2 } // namespace media } // namespace google } // namespace vendor media/libstagefright/codec2/hidl/impl/1.0/Configurable.cpp 0 → 100644 +167 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "Codec2-Configurable" #include <log/log.h> #include <codec2/hidl/1.0/Configurable.h> #include <codec2/hidl/1.0/ComponentStore.h> #include <codec2/hidl/1.0/types.h> #include <C2ParamInternal.h> namespace vendor { namespace google { namespace media { namespace c2 { namespace V1_0 { namespace implementation { using namespace ::android; CachedConfigurable::CachedConfigurable( std::unique_ptr<ConfigurableC2Intf>&& intf) : mIntf(std::move(intf)) { } c2_status_t CachedConfigurable::init(ComponentStore* store) { // Retrieve supported parameters from store c2_status_t init = mIntf->querySupportedParams(&mSupportedParams); c2_status_t validate = store->validateSupportedParams(mSupportedParams); return init == C2_OK ? C2_OK : validate; } // Methods from ::android::hardware::media::c2::V1_0::IConfigurable follow. Return<void> CachedConfigurable::getName(getName_cb _hidl_cb) { _hidl_cb(mIntf->getName()); return Void(); } Return<void> CachedConfigurable::query( const hidl_vec<uint32_t>& indices, bool mayBlock, query_cb _hidl_cb) { typedef C2Param::Index Index; std::vector<Index> c2heapParamIndices( (Index*)indices.data(), (Index*)indices.data() + indices.size()); std::vector<std::unique_ptr<C2Param>> c2heapParams; c2_status_t c2res = mIntf->query( c2heapParamIndices, mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK, &c2heapParams); hidl_vec<uint8_t> params; createParamsBlob(¶ms, c2heapParams); _hidl_cb(static_cast<Status>(c2res), params); return Void(); } Return<void> CachedConfigurable::config( const hidl_vec<uint8_t>& inParams, bool mayBlock, config_cb _hidl_cb) { std::vector<C2Param*> c2params; if (parseParamsBlob(&c2params, inParams) != C2_OK) { _hidl_cb(Status::CORRUPTED, hidl_vec<SettingResult>(), hidl_vec<uint8_t>()); return Void(); } // TODO: check if blob was invalid std::vector<std::unique_ptr<C2SettingResult>> c2failures; c2_status_t c2res = mIntf->config( c2params, mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK, &c2failures); hidl_vec<SettingResult> failures(c2failures.size()); { size_t ix = 0; for (const std::unique_ptr<C2SettingResult>& c2result : c2failures) { if (c2result) { objcpy(&failures[ix++], *c2result); } } failures.resize(ix); } hidl_vec<uint8_t> outParams; createParamsBlob(&outParams, c2params); _hidl_cb((Status)c2res, failures, outParams); return Void(); } Return<void> CachedConfigurable::querySupportedParams( uint32_t start, uint32_t count, querySupportedParams_cb _hidl_cb) { C2LinearRange request = C2LinearCapacity(mSupportedParams.size()).range( start, count); hidl_vec<ParamDescriptor> params(request.size()); Status res = Status::OK; size_t dstIx = 0; for (size_t srcIx = request.offset(); srcIx < request.endOffset(); ++srcIx) { if (mSupportedParams[srcIx]) { objcpy(¶ms[dstIx++], *mSupportedParams[srcIx]); } else { res = Status::CORRUPTED; } } params.resize(dstIx); _hidl_cb(res, params); return Void(); } Return<void> CachedConfigurable::querySupportedValues( const hidl_vec<FieldSupportedValuesQuery>& inFields, bool mayBlock, querySupportedValues_cb _hidl_cb) { std::vector<C2FieldSupportedValuesQuery> c2fields; { // C2FieldSupportedValuesQuery objects are restricted in that some // members are const. // C2ParamField - required for its constructor - has no constructors // from fields. Use C2ParamInspector. for (const FieldSupportedValuesQuery &query : inFields) { c2fields.emplace_back(_C2ParamInspector::CreateParamField( query.field.index, query.field.fieldId.offset, query.field.fieldId.size), query.type == FieldSupportedValuesQuery::Type::POSSIBLE ? C2FieldSupportedValuesQuery::POSSIBLE : C2FieldSupportedValuesQuery::CURRENT); } } c2_status_t c2res = mIntf->querySupportedValues( c2fields, mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK); hidl_vec<FieldSupportedValuesQueryResult> outFields(inFields.size()); { size_t ix = 0; for (const C2FieldSupportedValuesQuery &result : c2fields) { objcpy(&outFields[ix++], result); } } _hidl_cb((Status)c2res, outFields); return Void(); } } // namespace implementation } // namespace V1_0 } // namespace c2 } // namespace media } // namespace google } // namespace vendor media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/Component.h 0 → 100644 +85 −0 Original line number Diff line number Diff line #ifndef VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENT_H #define VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENT_H #include <codec2/hidl/1.0/Configurable.h> #include <vendor/google/media/c2/1.0/IComponentListener.h> #include <vendor/google/media/c2/1.0/IComponentStore.h> #include <vendor/google/media/c2/1.0/IComponent.h> #include <hidl/MQDescriptor.h> #include <hidl/Status.h> #include <C2Component.h> #include <C2.h> namespace vendor { namespace google { namespace media { namespace c2 { namespace V1_0 { namespace implementation { using ::android::hardware::hidl_array; using ::android::hardware::hidl_memory; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::sp; struct ComponentStore; struct ComponentInterface : public Configurable<IComponentInterface> { ComponentInterface( const std::shared_ptr<C2ComponentInterface>& interface, const sp<ComponentStore>& store); c2_status_t status() const; protected: c2_status_t mInit; std::shared_ptr<C2ComponentInterface> mInterface; // sp<ComponentStore> mStore; // TODO needed? }; struct Component : public Configurable<IComponent> { Component( const std::shared_ptr<C2Component>&, const sp<IComponentListener>& listener, const sp<ComponentStore>& store); // Methods from gIComponent follow. virtual Return<Status> queue(const WorkBundle& workBundle) override; virtual Return<void> flush(flush_cb _hidl_cb) override; virtual Return<Status> drain(bool withEos) override; virtual Return<Status> connectToInputSurface( const sp<IInputSurface>& surface) override; virtual Return<Status> connectToOmxInputSurface( const sp<::android::hardware::graphics::bufferqueue::V1_0:: IGraphicBufferProducer>& producer, const sp<::android::hardware::media::omx::V1_0:: IGraphicBufferSource>& source) override; virtual Return<Status> disconnectFromInputSurface() override; virtual Return<void> createBlockPool( uint32_t allocatorId, createBlockPool_cb _hidl_cb) override; virtual Return<Status> start() override; virtual Return<Status> stop() override; virtual Return<Status> reset() override; virtual Return<Status> release() override; protected: c2_status_t mInit; std::shared_ptr<C2Component> mComponent; std::shared_ptr<C2ComponentInterface> mInterface; sp<IComponentListener> mListener; // sp<ComponentStore> mStore; // TODO needed? }; } // namespace implementation } // namespace V1_0 } // namespace c2 } // namespace media } // namespace google } // namespace vendor #endif // VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENT_H Loading
media/libstagefright/codec2/hidl/impl/1.0/Android.bp 0 → 100644 +42 −0 Original line number Diff line number Diff line cc_library { name: "libstagefright_codec2_hidl@1.0", vendor_available: true, vndk: { enabled: true, }, defaults: ["hidl_defaults"], srcs: [ "Component.cpp", "ComponentStore.cpp", "Configurable.cpp", "types.cpp", ], shared_libs: [ "android.hardware.media.bufferpool@1.0", "libcutils", "libhidlbase", "libhidltransport", "liblog", "libstagefright_codec2", "libstagefright_codec2_vndk", "libutils", "vendor.google.media.c2@1.0", ], export_include_dirs: [ "include", ], export_shared_lib_headers: [ "libstagefright_codec2", ], // Private include directories header_libs: [ "libstagefright_codec2_internal", ], }
media/libstagefright/codec2/hidl/impl/1.0/Component.cpp 0 → 100644 +245 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "Codec2-Component" #include <log/log.h> #include <codec2/hidl/1.0/Component.h> #include <codec2/hidl/1.0/types.h> namespace vendor { namespace google { namespace media { namespace c2 { namespace V1_0 { namespace implementation { using namespace ::android; // Implementation of ConfigurableC2Intf based on C2ComponentInterface struct CompIntf : public ConfigurableC2Intf { CompIntf(const std::shared_ptr<C2ComponentInterface>& intf) : ConfigurableC2Intf(intf->getName()), mIntf(intf) { } virtual c2_status_t config( const std::vector<C2Param*>& params, c2_blocking_t mayBlock, std::vector<std::unique_ptr<C2SettingResult>>* const failures ) override { return mIntf->config_vb(params, mayBlock, failures); } virtual c2_status_t query( const std::vector<C2Param::Index>& indices, c2_blocking_t mayBlock, std::vector<std::unique_ptr<C2Param>>* const params) override { return mIntf->query_vb({}, indices, mayBlock, params); } virtual c2_status_t querySupportedParams( std::vector<std::shared_ptr<C2ParamDescriptor>>* const params ) const override { return mIntf->querySupportedParams_nb(params); } virtual c2_status_t querySupportedValues( std::vector<C2FieldSupportedValuesQuery>& fields, c2_blocking_t mayBlock) const override { return mIntf->querySupportedValues_vb(fields, mayBlock); } protected: std::shared_ptr<C2ComponentInterface> mIntf; }; // ComponentInterface ComponentInterface::ComponentInterface( const std::shared_ptr<C2ComponentInterface>& intf, const sp<ComponentStore>& store) : Configurable(new CachedConfigurable(std::make_unique<CompIntf>(intf))), mInterface(intf) { mInit = init(store.get()); } c2_status_t ComponentInterface::status() const { return mInit; } // ComponentListener wrapper struct Listener : public C2Component::Listener { Listener(const wp<IComponentListener>& listener) : mListener(listener) { // TODO: Should we track interface errors? We could reuse onError() or // create our own error channel. } virtual void onError_nb( std::weak_ptr<C2Component> /* c2component */, uint32_t errorCode) override { sp<IComponentListener> listener = mListener.promote(); if (listener) { listener->onError(Status::OK, errorCode); } } virtual void onTripped_nb( std::weak_ptr<C2Component> /* c2component */, std::vector<std::shared_ptr<C2SettingResult>> c2settingResult ) override { sp<IComponentListener> listener = mListener.promote(); if (listener) { hidl_vec<SettingResult> settingResults(c2settingResult.size()); size_t ix = 0; for (const std::shared_ptr<C2SettingResult> &c2result : c2settingResult) { if (c2result) { objcpy(&settingResults[ix++], *c2result); } } settingResults.resize(ix); listener->onTripped(settingResults); } } virtual void onWorkDone_nb( std::weak_ptr<C2Component> /* c2component */, std::list<std::unique_ptr<C2Work>> c2workItems) override { sp<IComponentListener> listener = mListener.promote(); if (listener) { WorkBundle workBundle; // TODO: Connect with bufferpool API to send Works & Buffers if (objcpy(&workBundle, c2workItems) != Status::OK) { ALOGE("onWorkDone() received corrupted work items."); return; } listener->onWorkDone(workBundle); // Finish buffer transfers: nothing else to do } } protected: wp<IComponentListener> mListener; }; // Component Component::Component( const std::shared_ptr<C2Component>& component, const sp<IComponentListener>& listener, const sp<ComponentStore>& store) : Configurable(new CachedConfigurable( std::make_unique<CompIntf>(component->intf()))), mComponent(component), mInterface(component->intf()), mListener(listener) /* , // TODO: Do we need store for anything? mStore(store)*/ { std::shared_ptr<C2Component::Listener> c2listener = std::make_shared<Listener>(listener); c2_status_t res = mComponent->setListener_vb(c2listener, C2_DONT_BLOCK); // Retrieve supported parameters from store // TODO: We could cache this per component/interface type mInit = init(store.get()); mInit = mInit != C2_OK ? res : mInit; } // Methods from ::android::hardware::media::c2::V1_0::IComponent Return<Status> Component::queue(const WorkBundle& workBundle) { std::list<std::unique_ptr<C2Work>> c2works; // TODO: Connect with bufferpool API for buffer transfers if (objcpy(&c2works, workBundle) != C2_OK) { return Status::CORRUPTED; } (void)workBundle; return static_cast<Status>(mComponent->queue_nb(&c2works)); } Return<void> Component::flush(flush_cb _hidl_cb) { std::list<std::unique_ptr<C2Work>> c2flushedWorks; c2_status_t c2res = mComponent->flush_sm( C2Component::FLUSH_COMPONENT, &c2flushedWorks); WorkBundle flushedWorkBundle; Status res = static_cast<Status>(c2res); if (c2res == C2_OK) { // TODO: Connect with bufferpool API for buffer transfers res = objcpy(&flushedWorkBundle, c2flushedWorks); } _hidl_cb(res, flushedWorkBundle); return Void(); } Return<Status> Component::drain(bool withEos) { return static_cast<Status>(mComponent->drain_nb(withEos ? C2Component::DRAIN_COMPONENT_WITH_EOS : C2Component::DRAIN_COMPONENT_NO_EOS)); } Return<Status> Component::connectToInputSurface(const sp<IInputSurface>& surface) { // TODO implement (void)surface; return Status::OK; } Return<Status> Component::connectToOmxInputSurface( const sp<::android::hardware::graphics::bufferqueue::V1_0:: IGraphicBufferProducer>& producer, const sp<::android::hardware::media::omx::V1_0:: IGraphicBufferSource>& source) { // TODO implement (void)producer; (void)source; return Status::OK; } Return<Status> Component::disconnectFromInputSurface() { // TODO implement return Status::OK; } Return<void> Component::createBlockPool(uint32_t allocatorId, createBlockPool_cb _hidl_cb) { // TODO implement (void)allocatorId; _hidl_cb(Status::OK, 0 /* blockPoolId */, nullptr /* configurable */); return Void(); } Return<Status> Component::start() { return static_cast<Status>(mComponent->start()); } Return<Status> Component::stop() { return static_cast<Status>(mComponent->stop()); } Return<Status> Component::reset() { return static_cast<Status>(mComponent->reset()); } Return<Status> Component::release() { return static_cast<Status>(mComponent->release()); } } // namespace implementation } // namespace V1_0 } // namespace c2 } // namespace media } // namespace google } // namespace vendor
media/libstagefright/codec2/hidl/impl/1.0/ComponentStore.cpp 0 → 100644 +212 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "Codec2-ComponentStore" #include <log/log.h> #include <codec2/hidl/1.0/ComponentStore.h> #include <codec2/hidl/1.0/Component.h> #include <codec2/hidl/1.0/ConfigurableC2Intf.h> #include <codec2/hidl/1.0/types.h> namespace vendor { namespace google { namespace media { namespace c2 { namespace V1_0 { namespace implementation { using namespace ::android; struct StoreIntf : public ConfigurableC2Intf { StoreIntf(const std::shared_ptr<C2ComponentStore>& store) : ConfigurableC2Intf(store ? store->getName() : ""), mStore(store) { } c2_status_t config( const std::vector<C2Param*> ¶ms, c2_blocking_t mayBlock, std::vector<std::unique_ptr<C2SettingResult>> *const failures ) override { // Assume all params are blocking // TODO: Filter for supported params if (mayBlock == C2_DONT_BLOCK && params.size() != 0) { return C2_BLOCKING; } return mStore->config_sm(params, failures); } c2_status_t query( const std::vector<C2Param::Index> &indices, c2_blocking_t mayBlock, std::vector<std::unique_ptr<C2Param>> *const params) override { // Assume all params are blocking // TODO: Filter for supported params if (mayBlock == C2_DONT_BLOCK && indices.size() != 0) { return C2_BLOCKING; } return mStore->query_sm({}, indices, params); } c2_status_t querySupportedParams( std::vector<std::shared_ptr<C2ParamDescriptor>> *const params ) const override { return mStore->querySupportedParams_nb(params); } c2_status_t querySupportedValues( std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const override { // Assume all params are blocking // TODO: Filter for supported params if (mayBlock == C2_DONT_BLOCK && fields.size() != 0) { return C2_BLOCKING; } return mStore->querySupportedValues_sm(fields); } protected: std::shared_ptr<C2ComponentStore> mStore; }; ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store) : Configurable(new CachedConfigurable(std::make_unique<StoreIntf>(store))), mStore(store) { // Retrieve struct descriptors mParamReflector = mStore->getParamReflector(); // Retrieve supported parameters from store mInit = init(this); } c2_status_t ComponentStore::validateSupportedParams( const std::vector<std::shared_ptr<C2ParamDescriptor>>& params) { c2_status_t res = C2_OK; for (const std::shared_ptr<C2ParamDescriptor> &desc : params) { if (!desc) { // All descriptors should be valid res = res ? res : C2_BAD_VALUE; continue; } C2Param::CoreIndex coreIndex = desc->index().coreIndex(); auto it = mStructDescriptors.find(coreIndex); if (it == mStructDescriptors.end()) { std::shared_ptr<C2StructDescriptor> structDesc = mParamReflector->describe(coreIndex); if (!structDesc) { // All supported params must be described res = C2_BAD_INDEX; } mStructDescriptors.insert({ coreIndex, structDesc }); } } return res; } // Methods from ::android::hardware::media::c2::V1_0::IComponentStore Return<void> ComponentStore::createComponent( const hidl_string& name, const sp<IComponentListener>& listener, // TODO: Return the pool if the component has it. const sp<IClientManager>& /* pool */, createComponent_cb _hidl_cb) { std::shared_ptr<C2Component> c2component; c2_status_t res = mStore->createComponent(name, &c2component); sp<IComponent> component; if (res == C2_OK) { component = new Component(c2component, listener, this); } _hidl_cb((Status)res, component); return Void(); } Return<void> ComponentStore::createInterface( const hidl_string& name, createInterface_cb _hidl_cb) { std::shared_ptr<C2ComponentInterface> c2interface; c2_status_t res = mStore->createInterface(name, &c2interface); sp<IComponentInterface> interface; if (res == C2_OK) { interface = new ComponentInterface(c2interface, this); } _hidl_cb((Status)res, interface); return Void(); } Return<void> ComponentStore::listComponents(listComponents_cb _hidl_cb) { std::vector<std::shared_ptr<const C2Component::Traits>> c2traits = mStore->listComponents(); hidl_vec<IComponentStore::ComponentTraits> traits(c2traits.size()); size_t ix = 0; for (const std::shared_ptr<const C2Component::Traits> &c2trait : c2traits) { if (c2trait) { objcpy(&traits[ix++], *c2trait); } } traits.resize(ix); _hidl_cb(traits); return Void(); } Return<sp<IInputSurface>> ComponentStore::createInputSurface() { // TODO implement return sp<IInputSurface> {}; } Return<void> ComponentStore::getStructDescriptors( const hidl_vec<uint32_t>& indices, getStructDescriptors_cb _hidl_cb) { hidl_vec<StructDescriptor> descriptors(indices.size()); size_t dstIx = 0; Status res; for (size_t srcIx = 0; srcIx < indices.size(); ++srcIx) { const auto item = mStructDescriptors.find( C2Param::CoreIndex(indices[srcIx]).coreIndex()); if (item == mStructDescriptors.end()) { res = Status::NOT_FOUND; } else if (item->second) { objcpy(&descriptors[dstIx++], *item->second); } else { res = Status::NO_MEMORY; } } descriptors.resize(dstIx); _hidl_cb(res, descriptors); return Void(); } Return<sp<IClientManager>> ComponentStore::getPoolClientManager() { // TODO implement return sp<IClientManager> {}; } Return<Status> ComponentStore::copyBuffer(const Buffer& src, const Buffer& dst) { // TODO implement (void)src; (void)dst; return Status {}; } } // namespace implementation } // namespace V1_0 } // namespace c2 } // namespace media } // namespace google } // namespace vendor
media/libstagefright/codec2/hidl/impl/1.0/Configurable.cpp 0 → 100644 +167 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "Codec2-Configurable" #include <log/log.h> #include <codec2/hidl/1.0/Configurable.h> #include <codec2/hidl/1.0/ComponentStore.h> #include <codec2/hidl/1.0/types.h> #include <C2ParamInternal.h> namespace vendor { namespace google { namespace media { namespace c2 { namespace V1_0 { namespace implementation { using namespace ::android; CachedConfigurable::CachedConfigurable( std::unique_ptr<ConfigurableC2Intf>&& intf) : mIntf(std::move(intf)) { } c2_status_t CachedConfigurable::init(ComponentStore* store) { // Retrieve supported parameters from store c2_status_t init = mIntf->querySupportedParams(&mSupportedParams); c2_status_t validate = store->validateSupportedParams(mSupportedParams); return init == C2_OK ? C2_OK : validate; } // Methods from ::android::hardware::media::c2::V1_0::IConfigurable follow. Return<void> CachedConfigurable::getName(getName_cb _hidl_cb) { _hidl_cb(mIntf->getName()); return Void(); } Return<void> CachedConfigurable::query( const hidl_vec<uint32_t>& indices, bool mayBlock, query_cb _hidl_cb) { typedef C2Param::Index Index; std::vector<Index> c2heapParamIndices( (Index*)indices.data(), (Index*)indices.data() + indices.size()); std::vector<std::unique_ptr<C2Param>> c2heapParams; c2_status_t c2res = mIntf->query( c2heapParamIndices, mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK, &c2heapParams); hidl_vec<uint8_t> params; createParamsBlob(¶ms, c2heapParams); _hidl_cb(static_cast<Status>(c2res), params); return Void(); } Return<void> CachedConfigurable::config( const hidl_vec<uint8_t>& inParams, bool mayBlock, config_cb _hidl_cb) { std::vector<C2Param*> c2params; if (parseParamsBlob(&c2params, inParams) != C2_OK) { _hidl_cb(Status::CORRUPTED, hidl_vec<SettingResult>(), hidl_vec<uint8_t>()); return Void(); } // TODO: check if blob was invalid std::vector<std::unique_ptr<C2SettingResult>> c2failures; c2_status_t c2res = mIntf->config( c2params, mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK, &c2failures); hidl_vec<SettingResult> failures(c2failures.size()); { size_t ix = 0; for (const std::unique_ptr<C2SettingResult>& c2result : c2failures) { if (c2result) { objcpy(&failures[ix++], *c2result); } } failures.resize(ix); } hidl_vec<uint8_t> outParams; createParamsBlob(&outParams, c2params); _hidl_cb((Status)c2res, failures, outParams); return Void(); } Return<void> CachedConfigurable::querySupportedParams( uint32_t start, uint32_t count, querySupportedParams_cb _hidl_cb) { C2LinearRange request = C2LinearCapacity(mSupportedParams.size()).range( start, count); hidl_vec<ParamDescriptor> params(request.size()); Status res = Status::OK; size_t dstIx = 0; for (size_t srcIx = request.offset(); srcIx < request.endOffset(); ++srcIx) { if (mSupportedParams[srcIx]) { objcpy(¶ms[dstIx++], *mSupportedParams[srcIx]); } else { res = Status::CORRUPTED; } } params.resize(dstIx); _hidl_cb(res, params); return Void(); } Return<void> CachedConfigurable::querySupportedValues( const hidl_vec<FieldSupportedValuesQuery>& inFields, bool mayBlock, querySupportedValues_cb _hidl_cb) { std::vector<C2FieldSupportedValuesQuery> c2fields; { // C2FieldSupportedValuesQuery objects are restricted in that some // members are const. // C2ParamField - required for its constructor - has no constructors // from fields. Use C2ParamInspector. for (const FieldSupportedValuesQuery &query : inFields) { c2fields.emplace_back(_C2ParamInspector::CreateParamField( query.field.index, query.field.fieldId.offset, query.field.fieldId.size), query.type == FieldSupportedValuesQuery::Type::POSSIBLE ? C2FieldSupportedValuesQuery::POSSIBLE : C2FieldSupportedValuesQuery::CURRENT); } } c2_status_t c2res = mIntf->querySupportedValues( c2fields, mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK); hidl_vec<FieldSupportedValuesQueryResult> outFields(inFields.size()); { size_t ix = 0; for (const C2FieldSupportedValuesQuery &result : c2fields) { objcpy(&outFields[ix++], result); } } _hidl_cb((Status)c2res, outFields); return Void(); } } // namespace implementation } // namespace V1_0 } // namespace c2 } // namespace media } // namespace google } // namespace vendor
media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/Component.h 0 → 100644 +85 −0 Original line number Diff line number Diff line #ifndef VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENT_H #define VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENT_H #include <codec2/hidl/1.0/Configurable.h> #include <vendor/google/media/c2/1.0/IComponentListener.h> #include <vendor/google/media/c2/1.0/IComponentStore.h> #include <vendor/google/media/c2/1.0/IComponent.h> #include <hidl/MQDescriptor.h> #include <hidl/Status.h> #include <C2Component.h> #include <C2.h> namespace vendor { namespace google { namespace media { namespace c2 { namespace V1_0 { namespace implementation { using ::android::hardware::hidl_array; using ::android::hardware::hidl_memory; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::sp; struct ComponentStore; struct ComponentInterface : public Configurable<IComponentInterface> { ComponentInterface( const std::shared_ptr<C2ComponentInterface>& interface, const sp<ComponentStore>& store); c2_status_t status() const; protected: c2_status_t mInit; std::shared_ptr<C2ComponentInterface> mInterface; // sp<ComponentStore> mStore; // TODO needed? }; struct Component : public Configurable<IComponent> { Component( const std::shared_ptr<C2Component>&, const sp<IComponentListener>& listener, const sp<ComponentStore>& store); // Methods from gIComponent follow. virtual Return<Status> queue(const WorkBundle& workBundle) override; virtual Return<void> flush(flush_cb _hidl_cb) override; virtual Return<Status> drain(bool withEos) override; virtual Return<Status> connectToInputSurface( const sp<IInputSurface>& surface) override; virtual Return<Status> connectToOmxInputSurface( const sp<::android::hardware::graphics::bufferqueue::V1_0:: IGraphicBufferProducer>& producer, const sp<::android::hardware::media::omx::V1_0:: IGraphicBufferSource>& source) override; virtual Return<Status> disconnectFromInputSurface() override; virtual Return<void> createBlockPool( uint32_t allocatorId, createBlockPool_cb _hidl_cb) override; virtual Return<Status> start() override; virtual Return<Status> stop() override; virtual Return<Status> reset() override; virtual Return<Status> release() override; protected: c2_status_t mInit; std::shared_ptr<C2Component> mComponent; std::shared_ptr<C2ComponentInterface> mInterface; sp<IComponentListener> mListener; // sp<ComponentStore> mStore; // TODO needed? }; } // namespace implementation } // namespace V1_0 } // namespace c2 } // namespace media } // namespace google } // namespace vendor #endif // VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENT_H