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(); }
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; } }
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; }
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; }
status_t OMXNodeInstance::useBuffer( OMX_U32 portIndex, const sp<IMemory> ¶ms, 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; }