Ejemplo n.º 1
0
// receive a buffer from VideoCore either from the message bytes
// or by a bulk transfer receieve
OMX_BUFFERHEADERTYPE *vc_ilcs_receive_buffer(void *call, int clen, OMX_COMPONENTTYPE **pComp)
{
   IL_PASS_BUFFER_EXECUTE_T *exe = call;
   OMX_BUFFERHEADERTYPE *pHeader = exe->bufferHeader.pInputPortPrivate;
   OMX_U8 *pBuffer = pHeader->pBuffer;
   OMX_PTR *pAppPrivate = pHeader->pAppPrivate;
   OMX_PTR *pPlatformPrivate = pHeader->pPlatformPrivate;
   OMX_PTR *pInputPortPrivate = pHeader->pInputPortPrivate;
   OMX_PTR *pOutputPortPrivate = pHeader->pOutputPortPrivate;

   vc_assert(pHeader);
   memcpy(pHeader, &exe->bufferHeader, sizeof(OMX_BUFFERHEADERTYPE));

   *pComp = exe->reference;

   pHeader->pBuffer = pBuffer;
   pHeader->pAppPrivate = pAppPrivate;
   pHeader->pPlatformPrivate = pPlatformPrivate;
   pHeader->pInputPortPrivate = pInputPortPrivate;
   pHeader->pOutputPortPrivate = pOutputPortPrivate;
   
   if(exe->method == IL_BUFFER_BULK)
   {
      vc_assert(VCHI_BULK_ALIGNED(pHeader->pBuffer));

      IL_BUFFER_BULK_T *fixup = (IL_BUFFER_BULK_T *) (exe+1);

      // bulk transfer from videocore to host
      uint8_t *start = pHeader->pBuffer + pHeader->nOffset;
      uint8_t *end   = start + pHeader->nFilledLen;
      int32_t bulk_len = pHeader->nFilledLen - fixup->headerlen - fixup->trailerlen;
      int32_t result;
      
      vc_assert(clen == sizeof(IL_PASS_BUFFER_EXECUTE_T) + sizeof(IL_BUFFER_BULK_T));

      result = vchi_bulk_queue_receive( vc_ilcsg.vchi_handle,
                                        start + fixup->headerlen,
                                        bulk_len,
                                        VCHI_FLAGS_BLOCK_UNTIL_QUEUED | VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE,
                                        NULL );
      vc_assert(result == 0);
      
      if (fixup->headerlen)
         memcpy(start, fixup->header, fixup->headerlen);
      if (fixup->trailerlen)
         memcpy(end-fixup->trailerlen, fixup->trailer, fixup->trailerlen);
   }
   else if(exe->method == IL_BUFFER_INLINE)
   {
      IL_BUFFER_INLINE_T *buffer = (IL_BUFFER_INLINE_T *) (exe+1);

      vc_assert(clen == sizeof(IL_PASS_BUFFER_EXECUTE_T) + pHeader->nFilledLen);

      memcpy(pBuffer+pHeader->nOffset, buffer->buffer, pHeader->nFilledLen);
   }
   else if(exe->method == IL_BUFFER_NONE)
   {
      vc_assert(clen == sizeof(IL_PASS_BUFFER_EXECUTE_T));
   }
   else if(exe->method == IL_BUFFER_MAX)
   {
      vc_assert(0);
   }

   return pHeader;
}
Ejemplo n.º 2
0
static OMX_ERRORTYPE vcil_out_addBuffer(OMX_IN OMX_HANDLETYPE hComponent,
                                        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
                                        OMX_IN OMX_U32 nPortIndex,
                                        OMX_IN OMX_PTR pAppPrivate,
                                        OMX_IN OMX_U32 nSizeBytes,
                                        OMX_IN OMX_U8* pBuffer,
                                        OMX_IN void *eglImage,
                                        IL_FUNCTION_T func)
{
   OMX_COMPONENTTYPE *pComp = (OMX_COMPONENTTYPE *) hComponent;
   VC_PRIVATE_COMPONENT_T *comp;
   IL_ADD_BUFFER_EXECUTE_T exe;
   IL_ADD_BUFFER_RESPONSE_T resp;
   OMX_BUFFERHEADERTYPE *pHeader;
   VC_PRIVATE_PORT_T *port;
   ILCS_COMMON_T *st;
   int rlen = sizeof(resp);

   if (!(pComp && ppBufferHdr))
      return OMX_ErrorBadParameter;

   st = pComp->pApplicationPrivate;
   comp = (VC_PRIVATE_COMPONENT_T *) pComp->pComponentPrivate;

   port = find_port(comp, nPortIndex);
   if (!port) // bad port index
      return OMX_ErrorBadPortIndex;

   if (port->numBuffers > 0 && port->func != func)
   {
      // inconsistent use of usebuffer/allocatebuffer/eglimage
      // all ports must receive all buffers by exactly one of these methods
      vc_assert(port->func != func);
      return OMX_ErrorInsufficientResources;
   }
   port->func = func;

   if (!VCHI_BULK_ALIGNED(pBuffer))
   {
      // cannot transfer this buffer across the host interface
      return OMX_ErrorBadParameter;
   }

   pHeader = vcos_malloc(sizeof(*pHeader), "vcout buffer header");

   if (!pHeader)
      return OMX_ErrorInsufficientResources;

   if (func == IL_ALLOCATE_BUFFER)
   {
      pBuffer = vcos_malloc_aligned(nSizeBytes, ILCS_ALIGN, "vcout mapping buffer");
      if (!pBuffer)
      {
         vcos_free(pHeader);
         return OMX_ErrorInsufficientResources;
      }
   }

   exe.reference = comp->reference;
   exe.bufferReference = pHeader;
   exe.port = nPortIndex;
   exe.size = nSizeBytes;
   exe.eglImage = eglImage;

   if(ilcs_execute_function(st->ilcs, func, &exe, sizeof(exe), &resp, &rlen) < 0 || rlen != sizeof(resp))
      resp.err = OMX_ErrorHardware;

   if (resp.err == OMX_ErrorNone)
   {
      memcpy(pHeader, &resp.bufferHeader, sizeof(OMX_BUFFERHEADERTYPE));
      if (port->dir == OMX_DirOutput)
         pHeader->pOutputPortPrivate = resp.reference;
      else
         pHeader->pInputPortPrivate = resp.reference;

      if (func == IL_USE_EGL_IMAGE)
      {
         pHeader->pBuffer = (OMX_U8*)eglImage;
         port->bEGL = OMX_TRUE;
      }         
      else
      {
         pHeader->pBuffer = pBuffer;
         port->bEGL = OMX_FALSE;
      }

      pHeader->pAppPrivate = pAppPrivate;
      *ppBufferHdr = pHeader;
      port->numBuffers++;
   }
   else
   {
      if (func == IL_ALLOCATE_BUFFER)
         vcos_free(pBuffer);
      vcos_free(pHeader);
   }

   return resp.err;
}