Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 173d8836 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Initial commit for the Codec2.0 HAL"

parents 88cc9a5f 1c75a23d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -8,8 +8,10 @@ cc_library {

    srcs: [
        "Component.cpp",
        "ComponentInterface.cpp",
        "ComponentStore.cpp",
        "Configurable.cpp",
        "InputBufferManager.cpp",
        "InputSurface.cpp",
        "InputSurfaceConnection.cpp",
        "types.cpp",
+133 −711

File changed.

Preview size limit exceeded, changes collapsed.

+110 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "Codec2-ComponentInterface"
#include <android-base/logging.h>

#include <codec2/hidl/1.0/Component.h>
#include <codec2/hidl/1.0/ComponentInterface.h>
#include <codec2/hidl/1.0/ComponentStore.h>

#include <hidl/HidlBinderSupport.h>
#include <utils/Timers.h>

#include <C2BqBufferPriv.h>
#include <C2Debug.h>
#include <C2PlatformSupport.h>

#include <chrono>
#include <thread>

namespace android {
namespace hardware {
namespace media {
namespace c2 {
namespace V1_0 {
namespace utils {

using namespace ::android;

namespace /* unnamed */ {

// Implementation of ConfigurableC2Intf based on C2ComponentInterface
struct CompIntf : public ConfigurableC2Intf {
    CompIntf(const std::shared_ptr<C2ComponentInterface>& intf) :
        ConfigurableC2Intf{intf->getName(), intf->getId()},
        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
            ) const 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;
};

} // unnamed namespace

// ComponentInterface
ComponentInterface::ComponentInterface(
        const std::shared_ptr<C2ComponentInterface>& intf,
        ComponentStore* store)
      : mInterface{intf},
        mConfigurable{new CachedConfigurable(std::make_unique<CompIntf>(intf))} {
    mInit = mConfigurable->init(store);
}

c2_status_t ComponentInterface::status() const {
    return mInit;
}

Return<sp<IConfigurable>> ComponentInterface::getConfigurable() {
    return mConfigurable;
}

}  // namespace utils
}  // namespace V1_0
}  // namespace c2
}  // namespace media
}  // namespace hardware
}  // namespace android
+100 −96
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 * 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.
@@ -16,37 +16,25 @@

//#define LOG_NDEBUG 0
#define LOG_TAG "Codec2-ComponentStore"
#include <log/log.h>
#include <android-base/logging.h>

#include <codec2/hidl/1.0/ComponentStore.h>
#include <codec2/hidl/1.0/InputSurface.h>
#include <codec2/hidl/1.0/Component.h>
#include <codec2/hidl/1.0/ConfigurableC2Intf.h>
#include <codec2/hidl/1.0/types.h>

#include <android-base/file.h>
#include <media/stagefright/bqhelper/WGraphicBufferProducer.h>
#include <media/stagefright/bqhelper/GraphicBufferSource.h>
#include <utils/Errors.h>

#include <C2PlatformSupport.h>
#include <util/C2InterfaceHelper.h>

#include <utils/Errors.h>

#include <android-base/file.h>

#ifdef LOG
#undef LOG
#endif

#ifdef PLOG
#undef PLOG
#endif

#include <android-base/logging.h>

#include <chrono>
#include <ctime>
#include <iomanip>
#include <ostream>
#include <sstream>
#include <iomanip>

namespace android {
namespace hardware {
@@ -62,12 +50,12 @@ using namespace ::android::hardware::media::bufferpool::V2_0::implementation;
namespace /* unnamed */ {

struct StoreIntf : public ConfigurableC2Intf {
    StoreIntf(const std::shared_ptr<C2ComponentStore>& store) :
        ConfigurableC2Intf(store ? store->getName() : ""),
        mStore(store) {
    StoreIntf(const std::shared_ptr<C2ComponentStore>& store)
          : ConfigurableC2Intf{store ? store->getName() : "", 0},
            mStore{store} {
    }

    c2_status_t config(
    virtual c2_status_t config(
            const std::vector<C2Param*> &params,
            c2_blocking_t mayBlock,
            std::vector<std::unique_ptr<C2SettingResult>> *const failures
@@ -80,7 +68,7 @@ struct StoreIntf : public ConfigurableC2Intf {
        return mStore->config_sm(params, failures);
    }

    c2_status_t query(
    virtual c2_status_t query(
            const std::vector<C2Param::Index> &indices,
            c2_blocking_t mayBlock,
            std::vector<std::unique_ptr<C2Param>> *const params) const override {
@@ -92,13 +80,13 @@ struct StoreIntf : public ConfigurableC2Intf {
        return mStore->query_sm({}, indices, params);
    }

    c2_status_t querySupportedParams(
    virtual c2_status_t querySupportedParams(
            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params
            ) const override {
        return mStore->querySupportedParams_nb(params);
    }

    c2_status_t querySupportedValues(
    virtual c2_status_t querySupportedValues(
            std::vector<C2FieldSupportedValuesQuery> &fields,
            c2_blocking_t mayBlock) const override {
        // Assume all params are blocking
@@ -115,9 +103,9 @@ protected:

} // unnamed namespace

ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store) :
    Configurable(new CachedConfigurable(std::make_unique<StoreIntf>(store))),
    mStore(store) {
ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store)
      : mConfigurable{new CachedConfigurable(std::make_unique<StoreIntf>(store))},
        mStore{store} {

    std::shared_ptr<C2ComponentStore> platformStore = android::GetCodec2PlatformComponentStore();
    SetPreferredCodec2ComponentStore(store);
@@ -126,7 +114,11 @@ ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store) :
    mParamReflector = mStore->getParamReflector();

    // Retrieve supported parameters from store
    mInit = init(this);
    mInit = mConfigurable->init(this);
}

c2_status_t ComponentStore::status() const {
    return mInit;
}

c2_status_t ComponentStore::validateSupportedParams(
@@ -172,19 +164,15 @@ Return<void> ComponentStore::createComponent(
        component = new Component(c2component, listener, this, pool);
        if (!component) {
            status = Status::CORRUPTED;
        } else if (component->status() != C2_OK) {
        } else {
            reportComponentBirth(component.get());
            if (component->status() != C2_OK) {
                status = static_cast<Status>(component->status());
            } else {
                component->initListener(component);
                if (component->status() != C2_OK) {
                    status = static_cast<Status>(component->status());
            } else {
                std::lock_guard<std::mutex> lock(mComponentRosterMutex);
                component->setLocalId(
                        mComponentRoster.emplace(
                            Component::InterfaceKey(component),
                            c2component)
                        .first);
                }
            }
        }
    }
@@ -202,7 +190,7 @@ Return<void> ComponentStore::createInterface(
        onInterfaceLoaded(c2interface);
        interface = new ComponentInterface(c2interface, this);
    }
    _hidl_cb((Status)res, interface);
    _hidl_cb(static_cast<Status>(res), interface);
    return Void();
}

@@ -213,27 +201,35 @@ Return<void> ComponentStore::listComponents(listComponents_cb _hidl_cb) {
    size_t ix = 0;
    for (const std::shared_ptr<const C2Component::Traits> &c2trait : c2traits) {
        if (c2trait) {
            objcpy(&traits[ix++], *c2trait);
            if (objcpy(&traits[ix], *c2trait)) {
                ++ix;
            } else {
                break;
            }
        }
    }
    traits.resize(ix);
    _hidl_cb(traits);
    _hidl_cb(Status::OK, traits);
    return Void();
}

Return<sp<IInputSurface>> ComponentStore::createInputSurface() {
Return<void> ComponentStore::createInputSurface(createInputSurface_cb _hidl_cb) {
    sp<GraphicBufferSource> source = new GraphicBufferSource();
    if (source->initCheck() != OK) {
        return nullptr;
        _hidl_cb(Status::CORRUPTED, nullptr);
        return Void();
    }
    typedef ::android::hardware::graphics::bufferqueue::V1_0::
            IGraphicBufferProducer HGbp;
    typedef ::android::TWGraphicBufferProducer<HGbp> B2HGbp;
    return new InputSurface(
    sp<InputSurface> inputSurface = new InputSurface(
            this,
            std::make_shared<C2ReflectorHelper>(),
            new B2HGbp(source->getIGraphicBufferProducer()),
            source);
    _hidl_cb(inputSurface ? Status::OK : Status::NO_MEMORY,
             inputSurface);
    return Void();
}

void ComponentStore::onInterfaceLoaded(const std::shared_ptr<C2ComponentInterface> &intf) {
@@ -265,15 +261,25 @@ Return<void> ComponentStore::getStructDescriptors(
                    mUnsupportedStructDescriptors.emplace(coreIndex);
                } else {
                    mStructDescriptors.insert({ coreIndex, structDesc });
                    objcpy(&descriptors[dstIx++], *structDesc);
                    if (objcpy(&descriptors[dstIx], *structDesc)) {
                        ++dstIx;
                        continue;
                    }
                    res = Status::CORRUPTED;
                    break;
                }
            }
            res = Status::NOT_FOUND;
        } else if (item->second) {
            objcpy(&descriptors[dstIx++], *item->second);
            if (objcpy(&descriptors[dstIx], *item->second)) {
                ++dstIx;
                continue;
            }
            res = Status::CORRUPTED;
            break;
        } else {
            res = Status::NO_MEMORY;
            break;
        }
    }
    descriptors.resize(dstIx);
@@ -292,29 +298,29 @@ Return<Status> ComponentStore::copyBuffer(const Buffer& src, const Buffer& dst)
    return Status::OMITTED;
}

void ComponentStore::reportComponentDeath(
        const Component::LocalId& componentLocalId) {
    std::lock_guard<std::mutex> lock(mComponentRosterMutex);
    mComponentRoster.erase(componentLocalId);
Return<sp<IConfigurable>> ComponentStore::getConfigurable() {
    return mConfigurable;
}

std::shared_ptr<C2Component> ComponentStore::findC2Component(
        const sp<IComponent>& component) const {
// Called from createComponent() after a successful creation of `component`.
void ComponentStore::reportComponentBirth(Component* component) {
    ComponentStatus componentStatus;
    componentStatus.c2Component = component->mComponent;
    componentStatus.birthTime = std::chrono::system_clock::now();

    std::lock_guard<std::mutex> lock(mComponentRosterMutex);
    Component::LocalId it = mComponentRoster.find(
            Component::InterfaceKey(component));
    if (it == mComponentRoster.end()) {
        return std::shared_ptr<C2Component>();
    }
    return it->second.lock();
    mComponentRoster.emplace(component, componentStatus);
}

// Debug dump

namespace /* unnamed */ {
// Called from within the destructor of `component`. No virtual function calls
// are made on `component` here.
void ComponentStore::reportComponentDeath(Component* component) {
    std::lock_guard<std::mutex> lock(mComponentRosterMutex);
    mComponentRoster.erase(component);
}

// Dump component traits
std::ostream& dump(
// Dumps component traits.
std::ostream& ComponentStore::dump(
        std::ostream& out,
        const std::shared_ptr<const C2Component::Traits>& comp) {

@@ -334,25 +340,38 @@ std::ostream& dump(
    return out;
}

// Dump component
std::ostream& dump(
// Dumps component status.
std::ostream& ComponentStore::dump(
        std::ostream& out,
        const std::shared_ptr<C2Component>& comp) {
        ComponentStatus& compStatus) {

    constexpr const char indent[] = "    ";

    std::shared_ptr<C2ComponentInterface> intf = comp->intf();
    // Print birth time.
    std::chrono::milliseconds ms =
            std::chrono::duration_cast<std::chrono::milliseconds>(
                compStatus.birthTime.time_since_epoch());
    std::time_t birthTime = std::chrono::system_clock::to_time_t(
            compStatus.birthTime);
    std::tm tm = *std::localtime(&birthTime);
    out << indent << "Creation time: "
        << std::put_time(&tm, "%Y-%m-%d %H:%M:%S")
        << '.' << std::setfill('0') << std::setw(3) << ms.count() % 1000
        << std::endl;

    // Print name and id.
    std::shared_ptr<C2ComponentInterface> intf = compStatus.c2Component->intf();
    if (!intf) {
        out << indent << "Unknown -- null interface" << std::endl;
        out << indent << "Unknown component -- null interface" << std::endl;
        return out;
    }
    out << indent << "name: " << intf->getName() << std::endl;
    out << indent << "id: " << intf->getId() << std::endl;
    out << indent << "Name: " << intf->getName() << std::endl;
    out << indent << "Id: " << intf->getId() << std::endl;

    return out;
}

} // unnamed namespace

// Dumps information when lshal is called.
Return<void> ComponentStore::debug(
        const hidl_handle& handle,
        const hidl_vec<hidl_string>& /* args */) {
@@ -387,31 +406,16 @@ Return<void> ComponentStore::debug(
            }
        }

        // Retrieve the list of active components.
        std::list<std::shared_ptr<C2Component>> activeComps;
        {
            std::lock_guard<std::mutex> lock(mComponentRosterMutex);
            auto i = mComponentRoster.begin();
            while (i != mComponentRoster.end()) {
                std::shared_ptr<C2Component> c2comp = i->second.lock();
                if (!c2comp) {
                    auto j = i;
                    ++i;
                    mComponentRoster.erase(j);
                } else {
                    ++i;
                    activeComps.emplace_back(c2comp);
                }
            }
        }

        // Dump active components.
        {
            out << indent << "Active components:" << std::endl << std::endl;
        if (activeComps.size() == 0) {
            std::lock_guard<std::mutex> lock(mComponentRosterMutex);
            if (mComponentRoster.size() == 0) {
                out << indent << indent << "NONE" << std::endl << std::endl;
            } else {
            for (const std::shared_ptr<C2Component>& c2comp : activeComps) {
                dump(out, c2comp) << std::endl;
                for (auto& pair : mComponentRoster) {
                    dump(out, pair.second) << std::endl;
                }
            }
        }

+38 −11
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 * 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.
@@ -16,11 +16,12 @@

//#define LOG_NDEBUG 0
#define LOG_TAG "Codec2-Configurable"
#include <log/log.h>
#include <android-base/logging.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 android {
@@ -33,8 +34,8 @@ namespace utils {
using namespace ::android;

CachedConfigurable::CachedConfigurable(
        std::unique_ptr<ConfigurableC2Intf>&& intf) :
    mIntf(std::move(intf)) {
        std::unique_ptr<ConfigurableC2Intf>&& intf)
      : mIntf{std::move(intf)} {
}

c2_status_t CachedConfigurable::init(ComponentStore* store) {
@@ -45,6 +46,10 @@ c2_status_t CachedConfigurable::init(ComponentStore* store) {
}

// Methods from ::android::hardware::media::c2::V1_0::IConfigurable follow.
Return<uint32_t> CachedConfigurable::getId() {
    return mIntf->getId();
}

Return<void> CachedConfigurable::getName(getName_cb _hidl_cb) {
    _hidl_cb(mIntf->getName());
    return Void();
@@ -65,9 +70,10 @@ Return<void> CachedConfigurable::query(
            &c2heapParams);

    hidl_vec<uint8_t> params;
    createParamsBlob(&params, c2heapParams);
    if (!createParamsBlob(&params, c2heapParams)) {
        LOG(WARNING) << "query -- invalid output params.";
    }
    _hidl_cb(static_cast<Status>(c2res), params);

    return Void();
}

@@ -78,7 +84,8 @@ Return<void> CachedConfigurable::config(
    // inParams is not writable, so create a copy as config modifies the parameters
    hidl_vec<uint8_t> inParamsCopy = inParams;
    std::vector<C2Param*> c2params;
    if (parseParamsBlob(&c2params, inParamsCopy) != C2_OK) {
    if (!parseParamsBlob(&c2params, inParamsCopy)) {
        LOG(WARNING) << "config -- invalid input params.";
        _hidl_cb(Status::CORRUPTED,
                hidl_vec<SettingResult>(),
                hidl_vec<uint8_t>());
@@ -95,13 +102,20 @@ Return<void> CachedConfigurable::config(
        size_t ix = 0;
        for (const std::unique_ptr<C2SettingResult>& c2result : c2failures) {
            if (c2result) {
                objcpy(&failures[ix++], *c2result);
                if (objcpy(&failures[ix], *c2result)) {
                    ++ix;
                } else {
                    LOG(DEBUG) << "config -- invalid setting results.";
                    break;
                }
            }
        }
        failures.resize(ix);
    }
    hidl_vec<uint8_t> outParams;
    createParamsBlob(&outParams, c2params);
    if (!createParamsBlob(&outParams, c2params)) {
        LOG(DEBUG) << "config -- invalid output params.";
    }
    _hidl_cb((Status)c2res, failures, outParams);
    return Void();
}
@@ -117,7 +131,13 @@ Return<void> CachedConfigurable::querySupportedParams(
    size_t dstIx = 0;
    for (size_t srcIx = request.offset(); srcIx < request.endOffset(); ++srcIx) {
        if (mSupportedParams[srcIx]) {
            objcpy(&params[dstIx++], *mSupportedParams[srcIx]);
            if (objcpy(&params[dstIx], *mSupportedParams[srcIx])) {
                ++dstIx;
            } else {
                res = Status::CORRUPTED;
                LOG(WARNING) << "querySupportedParams -- invalid output params.";
                break;
            }
        } else {
            res = Status::BAD_INDEX;
        }
@@ -154,7 +174,14 @@ Return<void> CachedConfigurable::querySupportedValues(
    {
        size_t ix = 0;
        for (const C2FieldSupportedValuesQuery &result : c2fields) {
            objcpy(&outFields[ix++], result);
            if (!objcpy(&outFields[ix], result)) {
                ++ix;
            } else {
                outFields.resize(ix);
                c2res = C2_CORRUPTED;
                LOG(WARNING) << "querySupportedValues -- invalid output params.";
                break;
            }
        }
    }
    _hidl_cb((Status)c2res, outFields);
Loading