OMX_ERRORTYPE ISVProcThreadObserver::releaseBuffer(PORT_INDEX index, OMX_BUFFERHEADERTYPE* pBuffer, bool bFLush) { if (!mBaseComponent || !mComponent || !mpCallBacks) return OMX_ErrorUndefined; OMX_ERRORTYPE err = OMX_ErrorNone; if (bFLush) { pBuffer->nFilledLen = 0; pBuffer->nOffset = 0; err = mpCallBacks->FillBufferDone(&mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer); ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: flush pBuffer %p", __func__, pBuffer); return err; } if (index == kPortIndexInput) { pBuffer->nFilledLen = 0; pBuffer->nOffset = 0; pBuffer->nFlags = 0; if (mISVBufferManager != NULL) { ISVBuffer* isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer)); if (isvBuffer != NULL) isvBuffer->clearIfNeed(); } err = OMX_FillThisBuffer(mComponent, pBuffer); ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBuffer pBuffer %p", __func__, pBuffer); } else { err = mpCallBacks->FillBufferDone(&mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer); ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3); } return err; }
status_t ISVBufferManager::useBuffer(const sp<ANativeWindowBuffer> nativeBuffer) { Mutex::Autolock autoLock(mBufferLock); if (nativeBuffer == NULL || mBuffers.size() >= mBuffers.capacity()) return BAD_VALUE; for (uint32_t i = 0; i < mBuffers.size(); i++) { ISVBuffer* isvBuffer = mBuffers.itemAt(i); if (isvBuffer->getHandle() == (unsigned long)nativeBuffer->handle) { ALOGE("%s: this buffer 0x%08x has already been registered", __func__, nativeBuffer->handle); return UNKNOWN_ERROR; } } ISVBuffer* isvBuffer = new ISVBuffer(mWorker, (unsigned long)nativeBuffer->handle, (unsigned long)nativeBuffer->handle, nativeBuffer->width, nativeBuffer->height, nativeBuffer->stride, nativeBuffer->format, mMetaDataMode ? ISVBuffer::ISV_BUFFER_METADATA : ISVBuffer::ISV_BUFFER_GRALLOC); ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: add handle 0x%08x, and then mBuffers.size() %d", __func__, nativeBuffer->handle, mBuffers.size()); mBuffers.push_back(isvBuffer); return OK; }
OMX_ERRORTYPE ISVComponent::ISV_FillBufferDone( OMX_OUT OMX_HANDLETYPE __maybe_unused hComponent, OMX_OUT OMX_PTR pAppData, OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) { ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: %p <== buffer_handle_t %p. mVPPEnabled %d, mVPPOn %d", __func__, pBuffer, pBuffer->pBuffer, mVPPEnabled, mVPPOn); if (!mpCallBacks) { ALOGE("%s: no call back functions were registered.", __func__); return OMX_ErrorUndefined; } if(!mVPPEnabled || !mVPPOn || mVPPFlushing || pBuffer->nFilledLen == 0) { ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3); return mpCallBacks->FillBufferDone(&mBaseComponent, pAppData, pBuffer); } if (mOutputCropChanged && mISVBufferManager != NULL) { ISVBuffer* isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer)); if (isvBuffer != NULL) isvBuffer->setFlag(ISVBuffer::ISV_BUFFER_CROP_CHANGED); mOutputCropChanged = false; } mProcThread->addInput(pBuffer); return OMX_ErrorNone; }
status_t ISVBufferManager::useBuffer(unsigned long handle) { Mutex::Autolock autoLock(mBufferLock); if (handle == 0 || mBuffers.size() >= mBuffers.capacity()) return BAD_VALUE; for (uint32_t i = 0; i < mBuffers.size(); i++) { ISVBuffer* isvBuffer = mBuffers.itemAt(i); if (isvBuffer->getHandle() == handle) { ALOGE("%s: this buffer 0x%08lx has already been registered", __func__, handle); return UNKNOWN_ERROR; } } ISVBuffer* isvBuffer = new ISVBuffer(mWorker, handle, mMetaDataMode ? ISVBuffer::ISV_BUFFER_METADATA : ISVBuffer::ISV_BUFFER_GRALLOC, mNeedClearBuffers ? ISVBuffer::ISV_BUFFER_NEED_CLEAR : 0); ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: add handle 0x%08lx, and then mBuffers.size() %d", __func__, handle, mBuffers.size()); mBuffers.push_back(isvBuffer); return OK; }
ISVBuffer* ISVBufferManager::mapBuffer(unsigned long handle) { Mutex::Autolock autoLock(mBufferLock); for (uint32_t i = 0; i < mBuffers.size(); i++) { ISVBuffer* isvBuffer = mBuffers.itemAt(i); if (isvBuffer->getHandle() == handle) return isvBuffer; } return NULL; }
status_t ISVBufferManager::setBuffersFlag(uint32_t flag) { Mutex::Autolock autoLock(mBufferLock); if (flag & ISVBuffer::ISV_BUFFER_NEED_CLEAR) { if (mBuffers.size() == 0) mNeedClearBuffers = true; else { for (uint32_t i = 0; i < mBuffers.size(); i++) { ISVBuffer* isvBuffer = mBuffers.itemAt(i); isvBuffer->setFlag(ISVBuffer::ISV_BUFFER_NEED_CLEAR); } } } return OK; }
status_t ISVBufferManager::freeBuffer(unsigned long handle) { Mutex::Autolock autoLock(mBufferLock); for (uint32_t i = 0; i < mBuffers.size(); i++) { ISVBuffer* isvBuffer = mBuffers.itemAt(i); if (isvBuffer->getHandle() == handle) { delete isvBuffer; mBuffers.removeAt(i); ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: remove handle 0x%08x, and then mBuffers.size() %d", __func__, handle, mBuffers.size()); return OK; } } ALOGW("%s: can't find buffer %u", __func__, handle); return UNKNOWN_ERROR; }
OMX_ERRORTYPE ISVComponent::ISV_FillThisBuffer( OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) { if(!mVPPEnabled || !mVPPOn) return OMX_FillThisBuffer(mComponent, pBuffer); ISVBuffer* isvBuffer = NULL; if (mISVBufferManager != NULL) { isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer)); if (isvBuffer == NULL) { ALOGE("%s: failed to map ISVBuffer, set mVPPEnabled -->false", __func__); mVPPEnabled = false; return OMX_FillThisBuffer(mComponent, pBuffer); } if (OK != isvBuffer->initBufferInfo(mHackFormat)) { ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: isvBuffer %p failed to initBufferInfo", __func__, isvBuffer); mVPPEnabled = false; return OMX_FillThisBuffer(mComponent, pBuffer); } } if (mNumDecoderBuffers > 0) { mNumDecoderBuffers--; ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: fill pBuffer %p to the decoder, decoder still need extra %d buffers", __func__, pBuffer, mNumDecoderBuffers); if (isvBuffer != NULL) isvBuffer->clearIfNeed(); return OMX_FillThisBuffer(mComponent, pBuffer); } mProcThread->addOutput(pBuffer); return OMX_ErrorNone; }