Exemplo n.º 1
0
void* COMXVideo::BoblightClientThread(void* data){
  int rgb[3];
  unsigned int offset = 0;
  uint_fast16_t x=0, y=0;

  COMXCoreComponent* p_omx_split = ((COMXCoreComponent**)data)[0];
  COMXCoreComponent* p_omx_resize = ((COMXCoreComponent**)data)[1];

  OMX_BUFFERHEADERTYPE *omx_buffer_fb;
  OMX_PARAM_U32TYPE singlestep_param;
  OMX_INIT_STRUCTURE(singlestep_param);
  singlestep_param.nPortIndex = p_omx_split->GetOutputPort();               
  singlestep_param.nU32 = 1;

  while(1){
    if(COMXVideo::m_boblight_threadstop){
      pthread_exit(0);
    }

    //set the first splitter port into the single-image mode (video goes out through the second one)
    OMX_ERRORTYPE omx_err = p_omx_split->SetParameter(OMX_IndexConfigSingleStep, &singlestep_param);
    if(omx_err != OMX_ErrorNone)
    {
      CLog::Log(LOGERROR, "%s::%s - error OMX_IndexConfigSingleStep omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err);
    }
    
    //request a new screenshot
    omx_buffer_fb = p_omx_resize->GetOutputBuffer();
    p_omx_resize->FillThisBuffer(omx_buffer_fb); //the callback BufferDoneHandler will be triggered instantly

    //wait until a screenshot is available in the buffer
    pthread_mutex_lock(&COMXVideo::m_boblight_bufferdone_mutex);
    while (!COMXVideo::m_boblight_bufferdone_flag) {
      pthread_cond_wait(&COMXVideo::m_boblight_bufferdone_cond, &COMXVideo::m_boblight_bufferdone_mutex);
    }
    COMXVideo::m_boblight_bufferdone_flag = false;
    pthread_mutex_unlock(&COMXVideo::m_boblight_bufferdone_mutex);

    //process the screenshot
    if(COMXVideo::m_boblight_bufferpointer && COMXVideo::m_boblight_bufferpointer->nFilledLen != 0){
      x=COMXVideo::m_boblight_width-1;
      y=COMXVideo::m_boblight_height-1;
      //sorry for the bad readability, but using a down-counting loop helps to squeeze out some hundreds CPU cycles to reduce the boblight delay
      for(offset = (COMXVideo::m_boblight_width*COMXVideo::m_boblight_height)*4; offset>0; offset-=4){
        //process only if pixel is on the outer border of the image
        if( y<=COMXVideo::m_boblight_margin_t 
         || y>=COMXVideo::m_boblight_margin_b
         || x<=COMXVideo::m_boblight_margin_l
         || x>=COMXVideo::m_boblight_margin_r){

          //the buffer is filled in BGRA format -> extract RGB data boblight expects
          rgb[0] = (int)COMXVideo::m_boblight_bufferpointer->pBuffer[offset-2];
          rgb[1] = (int)COMXVideo::m_boblight_bufferpointer->pBuffer[offset-3];
          rgb[2] = (int)COMXVideo::m_boblight_bufferpointer->pBuffer[offset-4];

          boblight_addpixelxy(COMXVideo::m_boblight, x, y, rgb);
        }
        if(x==0){
          x=COMXVideo::m_boblight_width;
          --y;
        }

        --x;
      }
      boblight_sendrgb(COMXVideo::m_boblight, 0, NULL);
    }

    //the buffer was processed completely
    OMXClock::OMXSleep(COMXVideo::m_boblight_timeout);
  }
  pthread_exit(0); 
}
int cBoblight::writeColor(int *rgb, int x, int y)
{ 
	boblight_addpixelxy(m_boblight, x, y, rgb);

   return success;
}