image_t *clip_t::get_output_image( OfxTime time, OfxRectD *optionalBounds) { RAMEN_ASSERT( node()); RAMEN_ASSERT( node()->composition()); RAMEN_ASSERT( !node()->image_empty()); RAMEN_ASSERT( time == node()->composition()->frame()); RAMEN_ASSERT( getComponents() == kOfxImageComponentRGBA); RAMEN_ASSERT( getPixelDepth() == kOfxBitDepthFloat); Imath::Box2i area; if( optionalBounds) { area = Imath::Box2i( Imath::V2i( optionalBounds->x1, optionalBounds->y1), Imath::V2i( optionalBounds->x2 - 1, optionalBounds->y2 - 1)); area = Imath::scale( area, 1.0f / node()->render_context().subsample); area = node()->vertical_flip( area); } else area = node()->defined(); if( area.isEmpty()) { #ifndef NDEBUG DLOG( INFO) << "clip_t::getOutputImage, node = " << node()->name() << ", area == empty"; #endif return 0; } image::const_image_view_t view( node()->const_subimage_view( area)); int rowbytes; void *ptr = view_get_ptr_and_stride( view, rowbytes); // convert to OFX coordinate sys area = node()->vertical_flip( area); OfxRectI bounds; bounds.x1 = area.min.x; bounds.y1 = area.min.y; bounds.x2 = area.max.x + 1; bounds.y2 = area.max.y + 1; #ifndef NDEBUG DLOG( INFO) << "clip_t::getOutputImage, node = " << node()->name(); #endif return new image_t( *this, node()->image(), 1.0 / node()->render_context().subsample, ptr, bounds, bounds, rowbytes, std::string( "")); }
OMX_ERRORTYPE IFM_NmfProcessingComp::doBufferAllocation(OMX_U32 nPortIndex,OMX_U32 nBufferIndex,OMX_U32 nSizeBytes, \ OMX_U8 **ppData, void **ppBufferMetaData){ IN0("\n"); OMX_ERRORTYPE error = OMX_ErrorNone; OMX_PARAM_PORTDEFINITIONTYPE portdef; OMX_VERSIONTYPE version = {{0, 0, 0, 0}}; getOmxIlSpecVersion(&version); portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion = version; ENS_Port * port = mENSComponent.getPort(nPortIndex); port->getParameter(OMX_IndexParamPortDefinition, &portdef); MSG1("Allocating Buffer : 0x%lx bytes\n",nSizeBytes); if (portdef.eDomain == OMX_PortDomainVideo) { MMHwBuffer *sharedChunk=0; OMX_ERRORTYPE error; ENS_Port *port = mENSComponent.getPort(nPortIndex); if (nBufferIndex == 0) { MMHwBuffer::TBufferPoolCreationAttributes poolAttrs; poolAttrs.iBuffers = port->getBufferCountActual(); // Number of buffers in the pool poolAttrs.iDeviceType = MMHwBuffer::ESystemMemory; // Memory type poolAttrs.iDomainID = 0; // MPC Domain ID (only requested for MPC memory type) poolAttrs.iSize = nSizeBytes; // Size (in byte) of a buffer poolAttrs.iAlignment = 256; // Alignment applied to the base address of each buffer in the pool // 1,2,4,8,16,32,64 byte or -1 for MMU pageword size (default) poolAttrs.iCacheAttr = MMHwBuffer::ENormalCached; sharedChunk = NULL; error = MMHwBuffer::Create(poolAttrs, mENSComponent.getOMXHandle(), sharedChunk); if (error != OMX_ErrorNone) return OMX_ErrorInsufficientResources; port->setSharedChunk(sharedChunk); } // Let's now retrieve the "current" buffer sharedChunk = port->getSharedChunk(); MMHwBuffer::TBufferInfo bufferInfo; error = sharedChunk->BufferInfo(nBufferIndex, bufferInfo); if (error != OMX_ErrorNone) return OMX_ErrorInsufficientResources; *ppData = (OMX_U8 *)bufferInfo.iLogAddr; *ppBufferMetaData = sharedChunk; // Initialize extradata segment. int i = (int) (portdef.format.video.nFrameWidth * portdef.format.video.nFrameHeight * getPixelDepth(portdef.format.video.eColorFormat)); if (i > 0 && i < (int)nSizeBytes) memset((void *)&((*ppData)[i]), 0, (int)nSizeBytes - i); } else /* other : clock domain */ { OMX_U8 * ptr = (OMX_U8 *) new char[nSizeBytes]; if (ptr ==NULL) { return OMX_ErrorInsufficientResources; } *ppData = ptr; ptr = (OMX_U8 *) new char[sizeof(OMX_U32)]; *((OMX_U32 **) ppBufferMetaData) = (OMX_U32 *) ptr; *(OMX_U32 *) ptr = (OMX_U32) *ppData; } MSG1("pBuffer = %p\n",*ppData); MSG1("pBufferMetaData = %p\n",*ppBufferMetaData); OUTR(" ",error); return error; }
image_t *clip_t::get_input_image( OfxTime time, OfxRectD *optionalBounds) { RAMEN_ASSERT( node()); RAMEN_ASSERT( node()->composition()); RAMEN_ASSERT( port_ != -1); RAMEN_ASSERT( getPixelDepth() == kOfxBitDepthFloat); image_node_t *in = node()->input_as<image_node_t>( port()); if( !in) { #ifndef NDEBUG DLOG( INFO) << "clip_t::getImage, node = " << node()->name() << ", port = " << port() << ", result = 0"; #endif return 0; } render::context_t context = node()->render_context(); context.composition = node()->composition(); context.result_node = in; context.frame = time; render::context_guard_t guard( node()->composition()->current_context(), in); render::image_node_renderer_t r( context); Imath::Box2i area; if( optionalBounds) { // TODO: is this correct if the effect does not support tiles? area = Imath::Box2i( Imath::V2i( optionalBounds->x1, optionalBounds->y1), Imath::V2i( optionalBounds->x2 - 1, optionalBounds->y2 - 1)); area = node()->vertical_flip( area); r.render( area); area.min.x = optionalBounds->x1; area.min.y = optionalBounds->y1; area.max.x = optionalBounds->x2 - 1; area.max.y = optionalBounds->y2 - 1; area = node()->vertical_flip( area); area = intersect( in->defined(), area); } else { r.render(); area = in->defined(); } if( area.isEmpty()) { #ifndef NDEBUG DLOG( INFO) << "clip_t::getImage, node = " << node()->name() << ", port = " << port() << ", area == empty"; #endif return 0; } image::buffer_t pixels = in->image(); image::const_image_view_t view( in->const_subimage_view( area)); area = node()->vertical_flip( area); OfxRectI bounds; bounds.x1 = area.min.x; bounds.y1 = area.min.y; bounds.x2 = area.max.x + 1; bounds.y2 = area.max.y + 1; std::stringstream s; for( int i = 0; i < 16; ++i) s << (int) in->digest()[i]; #ifndef NDEBUG if( optionalBounds) DLOG( INFO) << "clip_t::getImage, node = " << node()->name() << ", port = " << port() << ", bounds = " << *optionalBounds; else DLOG( INFO) << "clip_t::getImage, node = " << node()->name() << ", port = " << port(); #endif image_t *result = 0; if( getComponents() == kOfxImageComponentRGBA) { int rowbytes; void *ptr = view_get_ptr_and_stride( view, rowbytes); result = new image_t( *this, pixels, 1.0 / node()->render_context().subsample, ptr, bounds, bounds, rowbytes, s.str()); } else { // TODO: create an gray scale image and copy the alpha channel RAMEN_ASSERT( 0); } in->release_image(); return result; }
OMX_ERRORTYPE IFM_HostNmfProcessingComp::allocateBuffer( OMX_U32 nPortIndex ,OMX_U32 nBufferIndex ,OMX_U32 nSizeBytes , OMX_U8 **ppData , void **ppBufferMetaData , void **portPrivateInfo){ IN0("\n"); OMX_ERRORTYPE error = OMX_ErrorNone; OMX_PARAM_PORTDEFINITIONTYPE portdef; OMX_VERSIONTYPE version = {{0, 0, 0, 0}}; getOmxIlSpecVersion(&version); portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion = version; ENS_Port * port = mENSComponent.getPort(nPortIndex); port->getParameter(OMX_IndexParamPortDefinition, &portdef); if (portdef.eDomain == OMX_PortDomainVideo) { error = allocateBufferVisual(nPortIndex, nBufferIndex, nSizeBytes, ppData, NULL, portPrivateInfo, OMX_FALSE); if (error != OMX_ErrorNone) return error; /* add a SharedBuffer tied to allocated buffers, because for HSMCamera we need to exchange Buffers * with DSP. TODO: other IFM-based components don't all need this, I should make this optional */ OMX_U32 bufPhysicalAddr; error = ((MMHwBuffer *)(*portPrivateInfo))->PhysAddress((OMX_U32)*ppData,nSizeBytes,bufPhysicalAddr); if (error != OMX_ErrorNone) return error; SharedBuffer *sharedBuf = new SharedBuffer(mENSComponent.getNMFDomainHandle(), nSizeBytes, *ppData, bufPhysicalAddr, 0, NULL, error); if (sharedBuf == 0) { freeBufferVisual(nPortIndex,nBufferIndex,OMX_TRUE,NULL,*portPrivateInfo); return OMX_ErrorInsufficientResources; } if (error != OMX_ErrorNone) { freeBufferVisual(nPortIndex,nBufferIndex,OMX_TRUE,NULL,*portPrivateInfo); return error; } /* backup portPrivateInfo (actually an MMHwBuffer *) to ppBufferMetaData, which is stored in OMX_BUFFERHEADERTYPE.pPlatformPrivate by caller (NmfHost_ProcessingComponent->allocateBuffer). This is a hack to store the (MMHwBuffer *) somewhere easily accessible by NMF components, such as B2R2lib. Longer term solution would be to store it in sharedBuf. */ *ppBufferMetaData = *portPrivateInfo; *portPrivateInfo = (void *)sharedBuf; // Initialize extradata segment. int i = (int) (portdef.format.video.nFrameWidth * portdef.format.video.nFrameHeight * getPixelDepth(portdef.format.video.eColorFormat)); if (i > 0 && i < (int)nSizeBytes) memset((void *)&((*ppData)[i]), 0, (int)nSizeBytes - i); } else /* clock port*/ { error = allocateBufferHeap(nPortIndex,nBufferIndex,nSizeBytes,ppData,ppBufferMetaData,portPrivateInfo); if (error != OMX_ErrorNone) return error; } MSG1("pBuffer = %p\n",*ppData); MSG1("pBufferMetaData = %p\n",*ppBufferMetaData); OUTR(" ",error); return error; }