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

Commit 26a48f30 authored by Lajos Molnar's avatar Lajos Molnar
Browse files

stagefright: add support for batching OMX events

Bug: 20503131
Change-Id: I762c419ed1245f8b83fb1f6bf61e5557213ca07b
parent bf913163
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@
#include <utils/List.h>
#include <utils/String8.h>

#include <list>

#include <media/hardware/MetadataBufferType.h>

#include <OMX_Core.h>
@@ -231,7 +233,8 @@ class IOMXObserver : public IInterface {
public:
    DECLARE_META_INTERFACE(OMXObserver);

    virtual void onMessage(const omx_message &msg) = 0;
    // Handle (list of) messages.
    virtual void onMessages(const std::list<omx_message> &messages) = 0;
};

////////////////////////////////////////////////////////////////////////////////
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ private:
    enum {
        kWhatSetup                   = 'setu',
        kWhatOMXMessage              = 'omx ',
        kWhatOMXMessageList          = 'omxL',
        kWhatInputBufferFilled       = 'inpF',
        kWhatOutputBufferDrained     = 'outD',
        kWhatShutdown                = 'shut',
+40 −18
Original line number Diff line number Diff line
@@ -1077,17 +1077,30 @@ public:
        : BpInterface<IOMXObserver>(impl) {
    }

    virtual void onMessage(const omx_message &msg) {
    virtual void onMessages(const std::list<omx_message> &messages) {
        Parcel data, reply;
        std::list<omx_message>::const_iterator it = messages.cbegin();
        bool first = true;
        while (it != messages.cend()) {
            const omx_message &msg = *it++;
            if (first) {
                data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
        data.write(&msg, sizeof(msg));
                data.writeInt32(msg.node);
                first = false;
            }
            data.writeInt32(msg.fenceFd >= 0);
            if (msg.fenceFd >= 0) {
                data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
            }
            data.writeInt32(msg.type);
            data.write(&msg.u, sizeof(msg.u));
            ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));

        }
        if (!first) {
            data.writeInt32(-1); // mark end
            remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
        }
    }
};

IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
@@ -1098,19 +1111,28 @@ status_t BnOMXObserver::onTransact(
        case OBSERVER_ON_MSG:
        {
            CHECK_OMX_INTERFACE(IOMXObserver, data, reply);

            omx_message msg;
            data.read(&msg, sizeof(msg));
            if (msg.fenceFd >= 0) {
                msg.fenceFd = ::dup(data.readFileDescriptor());
            IOMX::node_id node = data.readInt32();
            std::list<omx_message> messages;
            status_t err = FAILED_TRANSACTION; // must receive at least one message
            do {
                int haveFence = data.readInt32();
                if (haveFence < 0) { // we use -1 to mark end of messages
                    break;
                }

                omx_message msg;
                msg.node = node;
                msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
                msg.type = (typeof(msg.type))data.readInt32();
                err = data.read(&msg.u, sizeof(msg.u));
                ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
                messages.push_back(msg);
            } while (err == OK);

            // XXX Could use readInplace maybe?
            onMessage(msg);
            if (err == OK) {
                onMessages(messages);
            }

            return NO_ERROR;
            return err;
        }

        default:
+98 −51
Original line number Diff line number Diff line
@@ -106,6 +106,16 @@ static void InitOMXParams(T *params) {
    params->nVersion.s.nStep = 0;
}

struct MessageList : public RefBase {
    MessageList() {
    }
    std::list<sp<AMessage> > &getList() { return mList; }
private:
    std::list<sp<AMessage> > mList;

    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
};

struct CodecObserver : public BnOMXObserver {
    CodecObserver() {}

@@ -114,12 +124,20 @@ struct CodecObserver : public BnOMXObserver {
    }

    // from IOMXObserver
    virtual void onMessage(const omx_message &omx_msg) {
        sp<AMessage> msg = mNotify->dup();

    virtual void onMessages(const std::list<omx_message> &messages) {
        sp<AMessage> notify;
        bool first = true;
        sp<MessageList> msgList = new MessageList();
        for (std::list<omx_message>::const_iterator it = messages.cbegin();
              it != messages.cend(); ++it) {
            const omx_message &omx_msg = *it;
            if (first) {
                notify = mNotify->dup();
                notify->setInt32("node", omx_msg.node);
            }

            sp<AMessage> msg = new AMessage;
            msg->setInt32("type", omx_msg.type);
        msg->setInt32("node", omx_msg.node);

            switch (omx_msg.type) {
                case omx_message::EVENT:
                {
@@ -161,8 +179,10 @@ struct CodecObserver : public BnOMXObserver {
                    ALOGE("Unrecognized message type: %d", omx_msg.type);
                    break;
            }

        msg->post();
            msgList->getList().push_back(msg);
        }
        notify->setObject("messages", msgList);
        notify->post();
    }

protected:
@@ -200,8 +220,15 @@ protected:
    void postFillThisBuffer(BufferInfo *info);

private:
    // Handles an OMX message. Returns true iff message was handled.
    bool onOMXMessage(const sp<AMessage> &msg);

    // Handles a list of messages. Returns true iff messages were handled.
    bool onOMXMessageList(const sp<AMessage> &msg);

    // returns true iff this message is for this component and the component is alive
    bool checkOMXMessage(const sp<AMessage> &msg);

    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);

    bool onOMXFillBufferDone(
@@ -4402,9 +4429,14 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
            break;
        }

        case ACodec::kWhatOMXMessageList:
        {
            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
        }

        case ACodec::kWhatOMXMessage:
        {
            return onOMXMessage(msg);
            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
        }

        case ACodec::kWhatSetSurface:
@@ -4463,16 +4495,13 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
    return true;
}

bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
    int32_t type;
    CHECK(msg->findInt32("type", &type));

bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
    // there is a possibility that this is an outstanding message for a
    // codec that we have already destroyed
    if (mCodec->mNode == 0) {
        ALOGI("ignoring message as already freed component: %s",
                msg->debugString().c_str());
        return true;
        return false;
    }

    IOMX::node_id nodeID;
@@ -4481,6 +4510,24 @@ bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
        return false;
    }
    return true;
}

bool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
    sp<RefBase> obj;
    CHECK(msg->findObject("messages", &obj));
    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());

    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
          it != msgList->getList().cend(); ++it) {
        onOMXMessage(*it);
    }
    return true;
}

bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
    int32_t type;
    CHECK(msg->findInt32("type", &type));

    switch (type) {
        case omx_message::EVENT:
@@ -5316,7 +5363,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
        return false;
    }

    notify = new AMessage(kWhatOMXMessage, mCodec);
    notify = new AMessage(kWhatOMXMessageList, mCodec);
    observer->setNotificationMessage(notify);

    mCodec->mComponentName = componentName;
+5 −2
Original line number Diff line number Diff line
@@ -116,12 +116,15 @@ struct OMXCodecObserver : public BnOMXObserver {
    }

    // from IOMXObserver
    virtual void onMessage(const omx_message &msg) {
    virtual void onMessages(const std::list<omx_message> &messages) {
        sp<OMXCodec> codec = mTarget.promote();

        if (codec.get() != NULL) {
            Mutex::Autolock autoLock(codec->mLock);
            codec->on_message(msg);
            for (std::list<omx_message>::const_iterator it = messages.cbegin();
                  it != messages.cend(); ++it) {
                codec->on_message(*it);
            }
            codec.clear();
        }
    }
Loading