예제 #1
0
int vc_ilcs_execute_function_usr(vcilcs_func_out_t* arg)
{
  vcilcs_func_out_t omxdesc;
  uint8_t cmd[VC_ILCS_MAX_CMD_LENGTH];
  uint8_t resp[VC_ILCS_MAX_CMD_LENGTH];
  void *data2 = NULL;
  int len2 = 0;
  IL_BUFFER_BULK_T fixup;

  //
  if(copy_from_user( &omxdesc, (void *)arg, sizeof(omxdesc)) != 0)
    {
      VC_DEBUG( Trace, "error, arg=0x%08X\n", (int)arg);
      return -EFAULT;
    }
  
  assert(omxdesc.len <= VC_ILCS_MAX_CMD_LENGTH);
  assert(omxdesc.resplen <= VC_ILCS_MAX_RESP_LENGTH);
  if(copy_from_user(cmd, omxdesc.data, omxdesc.len) != 0)
    {
      VC_DEBUG( Trace, "copy_from_user error, arg=0x%08X\n", (int)arg);
      return -EFAULT;
    }

  //  memset(resp, 0, omxdesc.resplen);
  if(IL_EMPTY_THIS_BUFFER == omxdesc.func)
    {
      omx_buffer_fixup((IL_PASS_BUFFER_EXECUTE_T*)cmd,&data2,&len2,&fixup);
    }
  
  //
  vc_ilcs_execute_function((IL_FUNCTION_T)omxdesc.func, cmd, omxdesc.len, data2, len2, resp, omxdesc.resplen);
  
  //
  if(copy_to_user((void *)omxdesc.resp, resp, omxdesc.resplen) != 0)
    {
      VC_DEBUG( Trace, "vc03: error, copy_to_user failed\n" );
      return -EFAULT;
    }
  
  return 0;
}
예제 #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;
}
예제 #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;
}