コード例 #1
0
status_t OMXNodeInstance::signalEndOfInputStream() {
    // For non-Surface input, the MediaCodec should convert the call to a
    // pair of requests (dequeue input buffer, queue input buffer with EOS
    // flag set).  Seems easier than doing the equivalent from here.
    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
    if (bufferSource == NULL) {
        ALOGW("signalEndOfInputStream can only be used with Surface input");
        return INVALID_OPERATION;
    };
    return bufferSource->signalEndOfInputStream();
}
コード例 #2
0
status_t OMXNodeInstance::setInternalOption(
        OMX_U32 portIndex,
        IOMX::InternalOptionType type,
        const void *data,
        size_t size) {
    switch (type) {
        case IOMX::INTERNAL_OPTION_SUSPEND:
        case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY:
        case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP:
        {
            const sp<GraphicBufferSource> &bufferSource =
                getGraphicBufferSource();

            if (bufferSource == NULL || portIndex != kPortIndexInput) {
                return ERROR_UNSUPPORTED;
            }

            if (type == IOMX::INTERNAL_OPTION_SUSPEND) {
                if (size != sizeof(bool)) {
                    return INVALID_OPERATION;
                }

                bool suspend = *(bool *)data;
                bufferSource->suspend(suspend);
            } else if (type ==
                    IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){
                if (size != sizeof(int64_t)) {
                    return INVALID_OPERATION;
                }

                int64_t delayUs = *(int64_t *)data;

                return bufferSource->setRepeatPreviousFrameDelayUs(delayUs);
            } else {
                if (size != sizeof(int64_t)) {
                    return INVALID_OPERATION;
                }

                int64_t maxGapUs = *(int64_t *)data;

                return bufferSource->setMaxTimestampGapUs(maxGapUs);
            }

            return OK;
        }

        default:
            return ERROR_UNSUPPORTED;
    }
}
コード例 #3
0
status_t OMXNodeInstance::createInputSurface(
        OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer) {
    Mutex::Autolock autolock(mLock);
    status_t err;

    const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource();
    if (surfaceCheck != NULL) {
        return ALREADY_EXISTS;
    }

    // Input buffers will hold meta-data (gralloc references).
    err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE);
    if (err != OK) {
        return err;
    }

    // Retrieve the width and height of the graphic buffer, set when the
    // codec was configured.
    OMX_PARAM_PORTDEFINITIONTYPE def;
    def.nSize = sizeof(def);
    def.nVersion.s.nVersionMajor = 1;
    def.nVersion.s.nVersionMinor = 0;
    def.nVersion.s.nRevision = 0;
    def.nVersion.s.nStep = 0;
    def.nPortIndex = portIndex;
    OMX_ERRORTYPE oerr = OMX_GetParameter(
            mHandle, OMX_IndexParamPortDefinition, &def);
    CHECK(oerr == OMX_ErrorNone);

    if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) {
        ALOGE("createInputSurface requires COLOR_FormatSurface "
              "(AndroidOpaque) color format");
        return INVALID_OPERATION;
    }

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

    *bufferProducer = bufferSource->getIGraphicBufferProducer();
    return OK;
}
コード例 #4
0
status_t OMXNodeInstance::allocateBuffer(
        OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
        void **buffer_data) {
    Mutex::Autolock autoLock(mLock);

    BufferMeta *buffer_meta = new BufferMeta(size);

    OMX_BUFFERHEADERTYPE *header;

    OMX_ERRORTYPE err = OMX_AllocateBuffer(
            mHandle, &header, portIndex, buffer_meta, size);

    if (err != OMX_ErrorNone) {
        ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);

        delete buffer_meta;
        buffer_meta = NULL;

        *buffer = 0;

        return UNKNOWN_ERROR;
    }

    CHECK_EQ(header->pAppPrivate, buffer_meta);

    *buffer = header;
    *buffer_data = header->pBuffer;

    addActiveBuffer(portIndex, *buffer);

    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
    if (bufferSource != NULL && portIndex == kPortIndexInput) {
        bufferSource->addCodecBuffer(header);
    }

    return OK;
}
コード例 #5
0
status_t OMXNodeInstance::useBuffer(
        OMX_U32 portIndex, const sp<IMemory> &params,
        OMX::buffer_id *buffer) {
    Mutex::Autolock autoLock(mLock);

    BufferMeta *buffer_meta = new BufferMeta(params);

    OMX_BUFFERHEADERTYPE *header;

    OMX_ERRORTYPE err = OMX_UseBuffer(
            mHandle, &header, portIndex, buffer_meta,
            params->size(), static_cast<OMX_U8 *>(params->pointer()));

    if (err != OMX_ErrorNone) {
        ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);

        delete buffer_meta;
        buffer_meta = NULL;

        *buffer = 0;

        return UNKNOWN_ERROR;
    }

    CHECK_EQ(header->pAppPrivate, buffer_meta);

    *buffer = header;

    addActiveBuffer(portIndex, *buffer);

    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
    if (bufferSource != NULL && portIndex == kPortIndexInput) {
        bufferSource->addCodecBuffer(header);
    }

    return OK;
}