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

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

Merge "codec2: list c2.* components in MediaCodecList"

parents 25070a91 78165d3f
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -141,6 +141,10 @@ bool MediaCodecInfo::isEncoder() const {
    return mIsEncoder;
}

uint32_t MediaCodecInfo::rank() const {
    return mRank;
}

void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
    mimes->clear();
    for (size_t ix = 0; ix < mCaps.size(); ix++) {
@@ -170,10 +174,12 @@ sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
    AString name = AString::FromParcel(parcel);
    AString owner = AString::FromParcel(parcel);
    bool isEncoder = static_cast<bool>(parcel.readInt32());
    uint32_t rank = parcel.readUint32();
    sp<MediaCodecInfo> info = new MediaCodecInfo;
    info->mName = name;
    info->mOwner = owner;
    info->mIsEncoder = isEncoder;
    info->mRank = rank;
    size_t size = static_cast<size_t>(parcel.readInt32());
    for (size_t i = 0; i < size; i++) {
        AString mime = AString::FromParcel(parcel);
@@ -191,6 +197,7 @@ status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
    mName.writeToParcel(parcel);
    mOwner.writeToParcel(parcel);
    parcel->writeInt32(mIsEncoder);
    parcel->writeUint32(mRank);
    parcel->writeInt32(mCaps.size());
    for (size_t i = 0; i < mCaps.size(); i++) {
        mCaps.keyAt(i).writeToParcel(parcel);
@@ -210,7 +217,7 @@ ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const {
    return -1;
}

MediaCodecInfo::MediaCodecInfo() {
MediaCodecInfo::MediaCodecInfo() : mRank(0x100) {
}

void MediaCodecInfoWriter::setName(const char* name) {
@@ -225,6 +232,10 @@ void MediaCodecInfoWriter::setEncoder(bool isEncoder) {
    mInfo->mIsEncoder = isEncoder;
}

void MediaCodecInfoWriter::setRank(uint32_t rank) {
    mInfo->mRank = rank;
}

std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
        MediaCodecInfoWriter::addMime(const char *mime) {
    ssize_t ix = mInfo->getCapabilityIndex(mime);
+9 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ struct MediaCodecInfo : public RefBase {
     * Currently, this is the "instance name" of the IOmx service.
     */
    const char *getOwnerName() const;
    uint32_t rank() const;

    /**
     * Serialization over Binder
@@ -182,6 +183,7 @@ private:
    AString mOwner;
    bool mIsEncoder;
    KeyedVector<AString, sp<Capabilities> > mCaps;
    uint32_t mRank;

    ssize_t getCapabilityIndex(const char *mime) const;

@@ -252,6 +254,13 @@ struct MediaCodecInfoWriter {
     * @return `true` if `mime` is removed; `false` if `mime` is not found.
     */
    bool removeMime(const char* mime);
    /**
     * Set rank of the codec. MediaCodecList will stable-sort the list according
     * to rank in non-descending order.
     *
     * @param rank The rank of the component.
     */
    void setRank(uint32_t rank);
private:
    /**
     * The associated `MediaCodecInfo`.
+38 −74
Original line number Diff line number Diff line
@@ -6349,11 +6349,9 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
    Vector<AString> matchingCodecs;
    Vector<AString> owners;

    AString mime;

    AString componentName;
    int32_t encoder = false;
    if (msg->findString("componentName", &componentName)) {
    CHECK(msg->findString("componentName", &componentName));

    sp<IMediaCodecList> list = MediaCodecList::getInstance();
    if (list == nullptr) {
        ALOGE("Unable to obtain MediaCodecList while "
@@ -6377,35 +6375,15 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
        mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR);
        return false;
    }
        matchingCodecs.add(info->getCodecName());
        owners.add(info->getOwnerName() == nullptr ?
                "default" : info->getOwnerName());
    } else {
        CHECK(msg->findString("mime", &mime));

        if (!msg->findInt32("encoder", &encoder)) {
            encoder = false;
        }

        MediaCodecList::findMatchingCodecs(
                mime.c_str(),
                encoder, // createEncoder
                0,       // flags
                &matchingCodecs,
                &owners);
    }
    AString owner = (info->getOwnerName() == nullptr) ? "default" : info->getOwnerName();

    sp<CodecObserver> observer = new CodecObserver;
    sp<IOMX> omx;
    sp<IOMXNode> omxNode;

    status_t err = NAME_NOT_FOUND;
    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
            ++matchIndex) {
        componentName = matchingCodecs[matchIndex];

    OMXClient client;
        if (client.connect(owners[matchIndex].c_str()) != OK) {
    if (client.connect(owner.c_str()) != OK) {
        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
        return false;
    }
@@ -6417,22 +6395,8 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
    err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
    androidSetThreadPriority(tid, prevPriority);

        if (err == OK) {
            break;
        } else {
            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
        }

        omxNode = NULL;
    }

    if (omxNode == NULL) {
        if (!mime.empty()) {
            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
                    encoder ? "en" : "de", mime.c_str(), err);
        } else {
    if (err != OK) {
        ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
        }

        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
        return false;
+1 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ cc_library_shared {
        "C2OMXNode.cpp",
        "CCodec.cpp",
        "CCodecBufferChannel.cpp",
        "Codec2InfoBuilder.cpp",
        "CodecBase.cpp",
        "CallbackDataSource.cpp",
        "CallbackMediaSource.cpp",
+55 −18
Original line number Diff line number Diff line
@@ -313,6 +313,19 @@ void CCodec::initiateConfigureComponent(const sp<AMessage> &format) {
}

void CCodec::configure(const sp<AMessage> &msg) {
    std::shared_ptr<C2ComponentInterface> intf;
    {
        Mutexed<State>::Locked state(mState);
        if (state->get() != ALLOCATED) {
            state->set(RELEASED);
            state.unlock();
            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
            state.lock();
            return;
        }
        intf = state->comp->intf();
    }

    sp<AMessage> inputFormat(new AMessage);
    sp<AMessage> outputFormat(new AMessage);
    if (status_t err = [=] {
@@ -332,11 +345,34 @@ void CCodec::configure(const sp<AMessage> &msg) {
            setSurface(surface);
        }

        std::vector<std::unique_ptr<C2Param>> params;
        std::initializer_list<C2Param::Index> indices {
            C2PortMimeConfig::input::PARAM_TYPE,
            C2PortMimeConfig::output::PARAM_TYPE,
        };
        c2_status_t c2err = intf->query_vb(
                {},
                indices,
                C2_DONT_BLOCK,
                &params);
        if (c2err != C2_OK) {
            ALOGE("Failed to query component interface: %d", c2err);
            return UNKNOWN_ERROR;
        }
        if (params.size() != indices.size()) {
            ALOGE("Component returns wrong number of params");
            return UNKNOWN_ERROR;
        }
        if (!params[0] || !params[1]) {
            ALOGE("Component returns null params");
            return UNKNOWN_ERROR;
        }
        inputFormat->setString("mime", ((C2PortMimeConfig *)params[0].get())->m.value);
        outputFormat->setString("mime", ((C2PortMimeConfig *)params[1].get())->m.value);

        // XXX: hack
        bool audio = mime.startsWithIgnoreCase("audio/");
        if (encoder) {
            outputFormat->setString("mime", mime);
            inputFormat->setString("mime", AStringPrintf("%s/raw", audio ? "audio" : "video"));
            if (audio) {
                inputFormat->setInt32("channel-count", 1);
                inputFormat->setInt32("sample-rate", 44100);
@@ -347,8 +383,6 @@ void CCodec::configure(const sp<AMessage> &msg) {
                outputFormat->setInt32("height", 1920);
            }
        } else {
            inputFormat->setString("mime", mime);
            outputFormat->setString("mime", AStringPrintf("%s/raw", audio ? "audio" : "video"));
            if (audio) {
                outputFormat->setInt32("channel-count", 2);
                outputFormat->setInt32("sample-rate", 44100);
@@ -712,7 +746,7 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatAllocate: {
            // C2ComponentStore::createComponent() should return within 100ms.
            setDeadline(now + 150ms);
            setDeadline(now + 150ms, "allocate");
            AString componentName;
            CHECK(msg->findString("componentName", &componentName));
            allocate(componentName);
@@ -720,7 +754,7 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) {
        }
        case kWhatConfigure: {
            // C2Component::commit_sm() should return within 5ms.
            setDeadline(now + 50ms);
            setDeadline(now + 50ms, "configure");
            sp<AMessage> format;
            CHECK(msg->findMessage("format", &format));
            configure(format);
@@ -728,31 +762,31 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) {
        }
        case kWhatStart: {
            // C2Component::start() should return within 500ms.
            setDeadline(now + 550ms);
            setDeadline(now + 550ms, "start");
            start();
            break;
        }
        case kWhatStop: {
            // C2Component::stop() should return within 500ms.
            setDeadline(now + 550ms);
            setDeadline(now + 550ms, "stop");
            stop();
            break;
        }
        case kWhatFlush: {
            // C2Component::flush_sm() should return within 5ms.
            setDeadline(now + 50ms);
            setDeadline(now + 50ms, "flush");
            flush();
            break;
        }
        case kWhatCreateInputSurface: {
            // Surface operations may be briefly blocking.
            setDeadline(now + 100ms);
            setDeadline(now + 100ms, "createInputSurface");
            createInputSurface();
            break;
        }
        case kWhatSetInputSurface: {
            // Surface operations may be briefly blocking.
            setDeadline(now + 100ms);
            setDeadline(now + 100ms, "setInputSurface");
            sp<RefBase> obj;
            CHECK(msg->findObject("surface", &obj));
            sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get()));
@@ -780,25 +814,28 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) {
            break;
        }
    }
    setDeadline(TimePoint::max());
    setDeadline(TimePoint::max(), "none");
}

void CCodec::setDeadline(const TimePoint &newDeadline) {
    Mutexed<TimePoint>::Locked deadline(mDeadline);
    *deadline = newDeadline;
void CCodec::setDeadline(const TimePoint &newDeadline, const char *name) {
    Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
    deadline->set(newDeadline, name);
}

void CCodec::initiateReleaseIfStuck() {
    std::string name;
    {
        Mutexed<TimePoint>::Locked deadline(mDeadline);
        if (*deadline >= std::chrono::steady_clock::now()) {
        Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
        if (deadline->get() >= std::chrono::steady_clock::now()) {
            // We're not stuck.
            return;
        }
        name = deadline->getName();
    }

    ALOGW("previous call to %s exceeded timeout", name.c_str());
    mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
    initiateRelease();
    initiateRelease(false);
}

}  // namespace android
Loading