Example #1
0
static void omx_buffer_fixup(IL_PASS_BUFFER_EXECUTE_T* data, void**data2, int*len2,IL_BUFFER_BULK_T *fixup)
{
  OMX_BUFFERHEADERTYPE* headptr;
  void* uaddr;
  vc_malloc_t desc;

   OMX_BUFFERHEADERTYPE *pBuffer;
   IL_RESPONSE_HEADER_T *resp;
   
   *data2 = NULL;
   *len2 = 0;
   
  if(NULL==data || NULL == data->bufferHeader.pBuffer)
	{
	  OMX_DEBUG("error: invalid / corrupt memory\n");
	  return;
	}
  
  headptr = &data->bufferHeader;
  uaddr = (void*)headptr->pBuffer;
  uaddr -= sizeof(desc);
  memcpy(&desc, uaddr, sizeof(desc));

  //
  if(desc.key != VC_MAGIC || NULL == desc.kaddr || NULL == desc.addr)
	{
	  OMX_DEBUG("error: invalid / corrupt memory\n");
	  return;
	}

  headptr->pPlatformPrivate =  headptr->pBuffer;
  headptr->pBuffer = desc.kaddr + sizeof(desc);
#if 0
  vchi_bulk_queue_transmit(vc_ilcs_vchi_handle(),
			   headptr->pBuffer + headptr->nOffset,
			   headptr->nFilledLen,
			   VCHI_FLAGS_BLOCK_UNTIL_QUEUED,
			   NULL );
#else
  pBuffer = headptr;
   if(pBuffer->nFilledLen)
   {
      if(pBuffer->nFilledLen + sizeof(IL_PASS_BUFFER_EXECUTE_T) <= VC_ILCS_MAX_INLINE)
      {
         data->method = IL_BUFFER_INLINE;
         *data2 = pBuffer->pBuffer + pBuffer->nOffset;
         *len2 = pBuffer->nFilledLen;
      }
      else
      {
         const uint8_t *start = pBuffer->pBuffer + pBuffer->nOffset;
         const uint8_t *end   = start + pBuffer->nFilledLen;
         const uint8_t *round_start = (const OMX_U8*)VCHI_BULK_ROUND_UP(start);
         const uint8_t *round_end   = (const OMX_U8*)VCHI_BULK_ROUND_DOWN(end);
         int bulk_len = round_end-round_start;
         int32_t result;

         data->method = IL_BUFFER_BULK;

         result = vchi_bulk_queue_transmit( vc_ilcsg.vchi_handle,
                                            round_start,
                                            round_end-round_start,
                                            VCHI_FLAGS_BLOCK_UNTIL_QUEUED,
                                            NULL );
         // when IL_EMPTY_THIS_BUFFER executes on videocore, there is a
         // corresponding vchi_bulk_queue_receive, which blocks until
         // complete (at which point, the above vchi_bulk_queue_transmit
         // must by definition have completed)
         
         vc_assert(result == 0);

         if((fixup->headerlen = round_start - start) > 0)
            memcpy(fixup->header, start, fixup->headerlen);

         if((fixup->trailerlen = end - round_end) > 0)
            memcpy(fixup->trailer, round_end, fixup->trailerlen);

         *data2 = fixup;
         *len2 = sizeof(IL_BUFFER_BULK_T);
      }
   }
   else
   {
      data->method = IL_BUFFER_NONE;
   }
#endif


}
Example #2
0
// send a buffer to VideoCore either by writing the buffer data in a control
// message or by sending an aligned bulk transfer with fixup information in the
// control message.
OMX_ERRORTYPE vc_ilcs_pass_buffer(IL_FUNCTION_T func, void *reference, OMX_BUFFERHEADERTYPE *pBuffer)
{
   IL_PASS_BUFFER_EXECUTE_T exe;
   IL_BUFFER_BULK_T fixup;
   IL_RESPONSE_HEADER_T resp;
   void *data2 = NULL;
   int len2 = 0;

   if ((func == IL_EMPTY_THIS_BUFFER && pBuffer->pInputPortPrivate == NULL) ||
         (func == IL_FILL_THIS_BUFFER && pBuffer->pOutputPortPrivate == NULL))
   {
      // return this to pass conformance
      // the actual error is using a buffer that hasn't be registered with usebuffer/allocatebuffer
      return OMX_ErrorIncorrectStateOperation;
   }

   exe.reference = reference;
   memcpy(&exe.bufferHeader, pBuffer, sizeof(OMX_BUFFERHEADERTYPE));

   if(pBuffer->nFilledLen)
   {
      if(pBuffer->nFilledLen + sizeof(IL_PASS_BUFFER_EXECUTE_T) <= VC_ILCS_MAX_INLINE)
      {
         exe.method = IL_BUFFER_INLINE;
         data2 = pBuffer->pBuffer + pBuffer->nOffset;
         len2 = pBuffer->nFilledLen;
      }
      else
      {
         const uint8_t *start = pBuffer->pBuffer + pBuffer->nOffset;
         const uint8_t *end   = start + pBuffer->nFilledLen;
         const uint8_t *round_start = (const OMX_U8*)VCHI_BULK_ROUND_UP(start);
         const uint8_t *round_end   = (const OMX_U8*)VCHI_BULK_ROUND_DOWN(end);
         int bulk_len = round_end-round_start;
         int32_t result;

         exe.method = IL_BUFFER_BULK;

         result = vchi_bulk_queue_transmit( vc_ilcsg.vchi_handle,
                                            round_start,
                                            round_end-round_start,
                                            VCHI_FLAGS_BLOCK_UNTIL_QUEUED,
                                            NULL );
         // when IL_EMPTY_THIS_BUFFER executes on videocore, there is a
         // corresponding vchi_bulk_queue_receive, which blocks until
         // complete (at which point, the above vchi_bulk_queue_transmit
         // must by definition have completed)
         
         vc_assert(result == 0);

         if((fixup.headerlen = round_start - start) > 0)
            memcpy(fixup.header, start, fixup.headerlen);

         if((fixup.trailerlen = end - round_end) > 0)
            memcpy(fixup.trailer, round_end, fixup.trailerlen);

         data2 = &fixup;
         len2 = sizeof(IL_BUFFER_BULK_T);
      }
   }
   else
   {
      exe.method = IL_BUFFER_NONE;
   }

   vc_ilcs_execute_function(func, &exe, sizeof(IL_PASS_BUFFER_EXECUTE_T), data2, len2, &resp, sizeof(resp));

   return resp.err;
}
Example #3
0
OMX_ERRORTYPE vc_ilcs_pass_buffer(IL_FUNCTION_T func, void *reference, OMX_BUFFERHEADERTYPE *pBuffer)
{
   IL_PASS_BUFFER_EXECUTE_T exe;
   IL_BUFFER_BULK_T fixup;
   IL_RESPONSE_HEADER_T resp;
   void *data2 = NULL;
   int len2 = 0;
   void *bulk = NULL;
   int bulk_len = 0;

   if ((func == IL_EMPTY_THIS_BUFFER && pBuffer->pInputPortPrivate == NULL) ||
         (func == IL_FILL_THIS_BUFFER && pBuffer->pOutputPortPrivate == NULL))
   {
      // return this to pass conformance
      // the actual error is using a buffer that hasn't be registered with usebuffer/allocatebuffer
      return OMX_ErrorIncorrectStateOperation;
   }

   exe.reference = reference;
   memcpy(&exe.bufferHeader, pBuffer, sizeof(OMX_BUFFERHEADERTYPE));

   exe.bufferLen = pBuffer->nFilledLen;
   if(pBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA)
   {
      OMX_U8 *ptr = pBuffer->pBuffer + pBuffer->nOffset + pBuffer->nFilledLen + 3;
      OMX_OTHER_EXTRADATATYPE *extra = (OMX_OTHER_EXTRADATATYPE *) (((uint32_t) ptr) & ~3);
      while(extra->eType != OMX_ExtraDataNone)
         extra = (OMX_OTHER_EXTRADATATYPE *) (((uint8_t *) extra) + extra->nSize);

      exe.bufferLen = (((uint8_t *) extra) + extra->nSize) - (pBuffer->pBuffer + pBuffer->nOffset);
   }

   if(exe.bufferLen)
   {
      if(exe.bufferLen + sizeof(IL_PASS_BUFFER_EXECUTE_T) <= VC_ILCS_MAX_INLINE)
      {
         exe.method = IL_BUFFER_INLINE;
         data2 = pBuffer->pBuffer + pBuffer->nOffset;
         len2 = exe.bufferLen;
      }
      else
      {
         const uint8_t *start = pBuffer->pBuffer + pBuffer->nOffset;
         const uint8_t *end   = start + exe.bufferLen;
         const uint8_t *round_start = (const OMX_U8*)VCHI_BULK_ROUND_UP(start);
         const uint8_t *round_end   = (const OMX_U8*)VCHI_BULK_ROUND_DOWN(end);

         exe.method = IL_BUFFER_BULK;
         bulk = (void *) round_start;
         bulk_len = round_end - round_start;

         if((fixup.headerlen = round_start - start) > 0)
            memcpy(fixup.header, start, fixup.headerlen);

         if((fixup.trailerlen = end - round_end) > 0)
            memcpy(fixup.trailer, round_end, fixup.trailerlen);

         data2 = &fixup;
         len2 = sizeof(IL_BUFFER_BULK_T);
      }
   }
   else
   {
      exe.method = IL_BUFFER_NONE;
   }

   if(vc_ilcs_execute_function(func, &exe, sizeof(IL_PASS_BUFFER_EXECUTE_T), data2, len2, bulk, bulk_len, &resp) < 0)
      return OMX_ErrorHardware;

   return resp.err;
}