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

Commit f779bb50 authored by Andy McFadden's avatar Andy McFadden
Browse files

Implement Surface input to MediaCodec.

Also, renamed a CHECK_INTERFACE macro that was clashing with the
Binder version.

Bug 7991062

Change-Id: If5e6ed0a06d9f67975497676e4b05abe3aa3d6c0
parent 10774e14
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#define ANDROID_IOMX_H_

#include <binder/IInterface.h>
#include <gui/IGraphicBufferProducer.h>
#include <ui/GraphicBuffer.h>
#include <utils/List.h>
#include <utils/String8.h>
@@ -96,6 +97,12 @@ public:
            node_id node, OMX_U32 port_index,
            const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) = 0;

    virtual status_t createInputSurface(
            node_id node, OMX_U32 port_index,
            sp<IGraphicBufferProducer> *bufferProducer) = 0;

    virtual status_t signalEndOfInputStream(node_id node) = 0;

    // This API clearly only makes sense if the caller lives in the
    // same process as the callee, i.e. is the media_server, as the
    // returned "buffer_data" pointer is just that, a pointer into local
+6 −0
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ struct ACodec : public AHierarchicalStateMachine {
        kWhatError               = 'erro',
        kWhatComponentAllocated  = 'cAll',
        kWhatComponentConfigured = 'cCon',
        kWhatInputSurfaceCreated = 'isfc',
        kWhatSignaledInputEOS    = 'seos',
        kWhatBuffersAllocated    = 'allc',
    };

@@ -55,9 +57,11 @@ struct ACodec : public AHierarchicalStateMachine {
    void initiateShutdown(bool keepComponentAllocated = false);

    void signalSetParameters(const sp<AMessage> &msg);
    void signalEndOfInputStream();

    void initiateAllocateComponent(const sp<AMessage> &msg);
    void initiateConfigureComponent(const sp<AMessage> &msg);
    void initiateCreateInputSurface();
    void initiateStart();

    void signalRequestIDRFrame();
@@ -105,6 +109,8 @@ private:
        kWhatDrainDeferredMessages   = 'drai',
        kWhatAllocateComponent       = 'allo',
        kWhatConfigureComponent      = 'conf',
        kWhatCreateInputSurface      = 'cisf',
        kWhatSignalEndOfInputStream  = 'eois',
        kWhatStart                   = 'star',
        kWhatRequestIDRFrame         = 'ridr',
        kWhatSetParameters           = 'setP',
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 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.
 */

#ifndef BUFFER_PRODUCER_WRAPPER_H_

#define BUFFER_PRODUCER_WRAPPER_H_

#include <gui/IGraphicBufferProducer.h>

namespace android {

// Can't use static_cast to cast a RefBase back to an IGraphicBufferProducer,
// because IGBP's parent (IInterface) uses virtual inheritance.  This class
// wraps IGBP while we pass it through AMessage.

struct BufferProducerWrapper : RefBase {
    BufferProducerWrapper(
            const sp<IGraphicBufferProducer>& bufferProducer) :
        mBufferProducer(bufferProducer) { }

    sp<IGraphicBufferProducer> getBufferProducer() const {
        return mBufferProducer;
    }

private:
    const sp<IGraphicBufferProducer> mBufferProducer;

    DISALLOW_EVIL_CONSTRUCTORS(BufferProducerWrapper);
};

}  // namespace android

#endif  // BUFFER_PRODUCER_WRAPPER_H_
+6 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ struct MediaCodec : public AHandler {
            const sp<ICrypto> &crypto,
            uint32_t flags);

    status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);

    status_t start();

    // Returns to a state in which the component remains allocated but
@@ -101,6 +103,8 @@ struct MediaCodec : public AHandler {
    status_t renderOutputBufferAndRelease(size_t index);
    status_t releaseOutputBuffer(size_t index);

    status_t signalEndOfInputStream();

    status_t getOutputFormat(sp<AMessage> *format) const;

    status_t getInputBuffers(Vector<sp<ABuffer> > *buffers) const;
@@ -143,6 +147,7 @@ private:
    enum {
        kWhatInit                           = 'init',
        kWhatConfigure                      = 'conf',
        kWhatCreateInputSurface             = 'cisf',
        kWhatStart                          = 'strt',
        kWhatStop                           = 'stop',
        kWhatRelease                        = 'rele',
@@ -150,6 +155,7 @@ private:
        kWhatQueueInputBuffer               = 'queI',
        kWhatDequeueOutputBuffer            = 'deqO',
        kWhatReleaseOutputBuffer            = 'relO',
        kWhatSignalEndOfInputStream         = 'eois',
        kWhatGetBuffers                     = 'getB',
        kWhatFlush                          = 'flus',
        kWhatGetOutputFormat                = 'getO',
+93 −20
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ enum {
    ENABLE_GRAPHIC_BUFFERS,
    USE_BUFFER,
    USE_GRAPHIC_BUFFER,
    CREATE_INPUT_SURFACE,
    SIGNAL_END_OF_INPUT_STREAM,
    STORE_META_DATA_IN_BUFFERS,
    ALLOC_BUFFER,
    ALLOC_BUFFER_WITH_BACKUP,
@@ -280,6 +282,45 @@ public:
        return err;
    }

    virtual status_t createInputSurface(
            node_id node, OMX_U32 port_index,
            sp<IGraphicBufferProducer> *bufferProducer) {
        Parcel data, reply;
        status_t err;
        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
        data.writeIntPtr((intptr_t)node);
        data.writeInt32(port_index);
        err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
        if (err != OK) {
            ALOGW("binder transaction failed: %d", err);
            return err;
        }

        err = reply.readInt32();
        if (err != OK) {
            return err;
        }

        *bufferProducer = IGraphicBufferProducer::asInterface(
                reply.readStrongBinder());

        return err;
    }

    virtual status_t signalEndOfInputStream(node_id node) {
        Parcel data, reply;
        status_t err;
        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
        data.writeIntPtr((intptr_t)node);
        err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply);
        if (err != OK) {
            ALOGW("binder transaction failed: %d", err);
            return err;
        }

        return reply.readInt32();
    }

    virtual status_t storeMetaDataInBuffers(
            node_id node, OMX_U32 port_index, OMX_BOOL enable) {
        Parcel data, reply;
@@ -404,7 +445,7 @@ IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");

////////////////////////////////////////////////////////////////////////////////

#define CHECK_INTERFACE(interface, data, reply) \
#define CHECK_OMX_INTERFACE(interface, data, reply) \
        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
            ALOGW("Call incorrectly routed to " #interface); \
            return PERMISSION_DENIED; \
@@ -415,7 +456,7 @@ status_t BnOMX::onTransact(
    switch (code) {
        case LIVES_LOCALLY:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);
            node_id node = (void *)data.readIntPtr();
            pid_t pid = (pid_t)data.readInt32();
            reply->writeInt32(livesLocally(node, pid));
@@ -425,7 +466,7 @@ status_t BnOMX::onTransact(

        case LIST_NODES:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            List<ComponentInfo> list;
            listNodes(&list);
@@ -448,7 +489,7 @@ status_t BnOMX::onTransact(

        case ALLOCATE_NODE:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            const char *name = data.readCString();

@@ -468,7 +509,7 @@ status_t BnOMX::onTransact(

        case FREE_NODE:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();

@@ -479,7 +520,7 @@ status_t BnOMX::onTransact(

        case SEND_COMMAND:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();

@@ -497,7 +538,7 @@ status_t BnOMX::onTransact(
        case GET_CONFIG:
        case SET_CONFIG:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
@@ -539,7 +580,7 @@ status_t BnOMX::onTransact(

        case GET_STATE:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_STATETYPE state = OMX_StateInvalid;
@@ -553,7 +594,7 @@ status_t BnOMX::onTransact(

        case ENABLE_GRAPHIC_BUFFERS:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_U32 port_index = data.readInt32();
@@ -567,7 +608,7 @@ status_t BnOMX::onTransact(

        case GET_GRAPHIC_BUFFER_USAGE:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_U32 port_index = data.readInt32();
@@ -582,7 +623,7 @@ status_t BnOMX::onTransact(

        case USE_BUFFER:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_U32 port_index = data.readInt32();
@@ -602,7 +643,7 @@ status_t BnOMX::onTransact(

        case USE_GRAPHIC_BUFFER:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_U32 port_index = data.readInt32();
@@ -621,9 +662,41 @@ status_t BnOMX::onTransact(
            return NO_ERROR;
        }

        case CREATE_INPUT_SURFACE:
        {
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_U32 port_index = data.readInt32();

            sp<IGraphicBufferProducer> bufferProducer;
            status_t err = createInputSurface(node, port_index,
                    &bufferProducer);

            reply->writeInt32(err);

            if (err == OK) {
                reply->writeStrongBinder(bufferProducer->asBinder());
            }

            return NO_ERROR;
        }

        case SIGNAL_END_OF_INPUT_STREAM:
        {
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();

            status_t err = signalEndOfInputStream(node);
            reply->writeInt32(err);

            return NO_ERROR;
        }

        case STORE_META_DATA_IN_BUFFERS:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_U32 port_index = data.readInt32();
@@ -637,7 +710,7 @@ status_t BnOMX::onTransact(

        case ALLOC_BUFFER:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_U32 port_index = data.readInt32();
@@ -659,7 +732,7 @@ status_t BnOMX::onTransact(

        case ALLOC_BUFFER_WITH_BACKUP:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_U32 port_index = data.readInt32();
@@ -681,7 +754,7 @@ status_t BnOMX::onTransact(

        case FREE_BUFFER:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            OMX_U32 port_index = data.readInt32();
@@ -693,7 +766,7 @@ status_t BnOMX::onTransact(

        case FILL_BUFFER:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            buffer_id buffer = (void*)data.readIntPtr();
@@ -704,7 +777,7 @@ status_t BnOMX::onTransact(

        case EMPTY_BUFFER:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            buffer_id buffer = (void*)data.readIntPtr();
@@ -723,7 +796,7 @@ status_t BnOMX::onTransact(

        case GET_EXTENSION_INDEX:
        {
            CHECK_INTERFACE(IOMX, data, reply);
            CHECK_OMX_INTERFACE(IOMX, data, reply);

            node_id node = (void*)data.readIntPtr();
            const char *parameter_name = data.readCString();
@@ -769,7 +842,7 @@ status_t BnOMXObserver::onTransact(
    switch (code) {
        case OBSERVER_ON_MSG:
        {
            CHECK_INTERFACE(IOMXObserver, data, reply);
            CHECK_OMX_INTERFACE(IOMXObserver, data, reply);

            omx_message msg;
            data.read(&msg, sizeof(msg));
Loading