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

Commit 512e9792 authored by Lajos Molnar's avatar Lajos Molnar
Browse files

stagefright: support passing GraphicBuffer in metadata buffer

Bug: 17935149
Change-Id: I6bb5dd654e498a7153410afc052c2c8f7f35e44d
parent e760de61
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -182,7 +182,9 @@ private:
            OMX_IN OMX_PTR pAppData,
            OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);

    status_t storeMetaDataInBuffers_l(OMX_U32 portIndex, OMX_BOOL enable);
    status_t storeMetaDataInBuffers_l(
            OMX_U32 portIndex, OMX_BOOL enable,
            OMX_BOOL useGraphicBuffer, OMX_BOOL *usingGraphicBufferInMeta);

    sp<GraphicBufferSource> getGraphicBufferSource();
    void setGraphicBufferSource(const sp<GraphicBufferSource>& bufferSource);
+39 −13
Original line number Diff line number Diff line
@@ -37,7 +37,8 @@ static const bool EXTRA_CHECK = true;


GraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance,
        uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount) :
        uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount,
        bool useGraphicBufferInMeta) :
    mInitCheck(UNKNOWN_ERROR),
    mNodeInstance(nodeInstance),
    mExecuting(false),
@@ -59,7 +60,8 @@ GraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance,
    mTimePerCaptureUs(-1ll),
    mTimePerFrameUs(-1ll),
    mPrevCaptureUs(-1ll),
    mPrevFrameUs(-1ll) {
    mPrevFrameUs(-1ll),
    mUseGraphicBufferInMeta(useGraphicBufferInMeta) {

    ALOGV("GraphicBufferSource w=%u h=%u c=%u",
            bufferWidth, bufferHeight, bufferCount);
@@ -254,6 +256,8 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
        // Pull the graphic buffer handle back out of the buffer, and confirm
        // that it matches expectations.
        OMX_U8* data = header->pBuffer;
        MetadataBufferType type = *(MetadataBufferType *)data;
        if (type == kMetadataBufferTypeGrallocSource) {
            buffer_handle_t bufferHandle;
            memcpy(&bufferHandle, data + 4, sizeof(buffer_handle_t));
            if (bufferHandle != codecBuffer.mGraphicBuffer->handle) {
@@ -262,6 +266,16 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
                        bufferHandle, codecBuffer.mGraphicBuffer->handle);
                CHECK(!"codecBufferEmptied: mismatched buffer");
            }
        } else if (type == kMetadataBufferTypeGraphicBuffer) {
            GraphicBuffer *buffer;
            memcpy(&buffer, data + 4, sizeof(buffer));
            if (buffer != codecBuffer.mGraphicBuffer.get()) {
                // should never happen
                ALOGE("codecBufferEmptied: buffer is %p, expected %p",
                        buffer, codecBuffer.mGraphicBuffer.get());
                CHECK(!"codecBufferEmptied: mismatched buffer");
            }
        }
    }

    // Find matching entry in our cached copy of the BufferQueue slots.
@@ -642,10 +656,22 @@ status_t GraphicBufferSource::submitBuffer_l(
    OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
    CHECK(header->nAllocLen >= 4 + sizeof(buffer_handle_t));
    OMX_U8* data = header->pBuffer;
    buffer_handle_t handle;
    if (!mUseGraphicBufferInMeta) {
        const OMX_U32 type = kMetadataBufferTypeGrallocSource;
    buffer_handle_t handle = codecBuffer.mGraphicBuffer->handle;
        handle = codecBuffer.mGraphicBuffer->handle;
        memcpy(data, &type, 4);
        memcpy(data + 4, &handle, sizeof(buffer_handle_t));
    } else {
        // codecBuffer holds a reference to the GraphicBuffer, so
        // it is valid while it is with the OMX component
        const OMX_U32 type = kMetadataBufferTypeGraphicBuffer;
        memcpy(data, &type, 4);
        // passing a non-reference-counted graphicBuffer
        GraphicBuffer *buffer = codecBuffer.mGraphicBuffer.get();
        handle = buffer->handle;
        memcpy(data + 4, &buffer, sizeof(buffer));
    }

    status_t err = mNodeInstance->emptyDirectBuffer(header, 0,
            4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME,
+4 −1
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@ namespace android {
class GraphicBufferSource : public BufferQueue::ConsumerListener {
public:
    GraphicBufferSource(OMXNodeInstance* nodeInstance,
            uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount);
            uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount,
            bool useGraphicBufferInMeta = false);
    virtual ~GraphicBufferSource();

    // We can't throw an exception if the constructor fails, so we just set
@@ -271,6 +272,8 @@ private:
    int64_t mPrevCaptureUs;
    int64_t mPrevFrameUs;

    bool mUseGraphicBufferInMeta;

    void onMessageReceived(const sp<AMessage> &msg);

    DISALLOW_EVIL_CONSTRUCTORS(GraphicBufferSource);
+29 −6
Original line number Diff line number Diff line
@@ -393,20 +393,39 @@ status_t OMXNodeInstance::storeMetaDataInBuffers(
        OMX_U32 portIndex,
        OMX_BOOL enable) {
    Mutex::Autolock autolock(mLock);
    return storeMetaDataInBuffers_l(portIndex, enable);
    return storeMetaDataInBuffers_l(
            portIndex, enable,
            OMX_FALSE /* useGraphicBuffer */, NULL /* usingGraphicBufferInMetadata */);
}

status_t OMXNodeInstance::storeMetaDataInBuffers_l(
        OMX_U32 portIndex,
        OMX_BOOL enable) {
        OMX_BOOL enable,
        OMX_BOOL useGraphicBuffer,
        OMX_BOOL *usingGraphicBufferInMetadata) {
    OMX_INDEXTYPE index;
    OMX_STRING name = const_cast<OMX_STRING>(
            "OMX.google.android.index.storeMetaDataInBuffers");

    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    OMX_STRING graphicBufferName = const_cast<OMX_STRING>(
            "OMX.google.android.index.storeGraphicBufferInMetaData");
    if (usingGraphicBufferInMetadata == NULL) {
        usingGraphicBufferInMetadata = &useGraphicBuffer;
    }

    OMX_ERRORTYPE err =
        (useGraphicBuffer && portIndex == kPortIndexInput)
                ? OMX_GetExtensionIndex(mHandle, graphicBufferName, &index)
                : OMX_ErrorBadParameter;
    if (err == OMX_ErrorNone) {
        *usingGraphicBufferInMetadata = OMX_TRUE;
    } else {
        *usingGraphicBufferInMetadata = OMX_FALSE;
        err = OMX_GetExtensionIndex(mHandle, name, &index);
    }

    if (err != OMX_ErrorNone) {
        ALOGE("OMX_GetExtensionIndex %s failed", name);

        return StatusFromOMXError(err);
    }

@@ -421,6 +440,7 @@ status_t OMXNodeInstance::storeMetaDataInBuffers_l(
    params.bStoreMetaData = enable;
    if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
        ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
        *usingGraphicBufferInMetadata = OMX_FALSE;
        return UNKNOWN_ERROR;
    }
    return err;
@@ -683,7 +703,10 @@ status_t OMXNodeInstance::createInputSurface(
    }

    // Input buffers will hold meta-data (gralloc references).
    err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE);
    OMX_BOOL usingGraphicBuffer = OMX_FALSE;
    err = storeMetaDataInBuffers_l(
            portIndex, OMX_TRUE,
            OMX_TRUE /* useGraphicBuffer */, &usingGraphicBuffer);
    if (err != OK) {
        return err;
    }
@@ -709,7 +732,7 @@ status_t OMXNodeInstance::createInputSurface(

    GraphicBufferSource* bufferSource = new GraphicBufferSource(
            this, def.format.video.nFrameWidth, def.format.video.nFrameHeight,
            def.nBufferCountActual);
            def.nBufferCountActual, usingGraphicBuffer);
    if ((err = bufferSource->initCheck()) != OK) {
        delete bufferSource;
        return err;