示例#1
0
文件: omx.c 项目: Ezio-PS/movian
void
omx_tunnel_destroy(omx_tunnel_t *ot)
{
  omxdbg("Destroying tunnel %s\n", ot->ot_name);
  omx_send_command(ot->ot_src, OMX_CommandPortDisable, ot->ot_srcport, NULL, 0);
  omx_send_command(ot->ot_dst, OMX_CommandPortDisable, ot->ot_dstport, NULL, 0);

  omx_wait_command(ot->ot_src);
  omx_wait_command(ot->ot_dst);

  omxchk(OMX_SetupTunnel(ot->ot_src->oc_handle, ot->ot_srcport, NULL, 0));
  free(ot);
}
示例#2
0
文件: omx.c 项目: Ezio-PS/movian
void
omx_alloc_buffers(omx_component_t *oc, int port)
{
  OMX_PARAM_PORTDEFINITIONTYPE portdef;

  memset(&portdef, 0, sizeof(portdef));
  portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
  portdef.nVersion.nVersion = OMX_VERSION;
  portdef.nPortIndex = port;

  omxchk(OMX_GetParameter(oc->oc_handle, OMX_IndexParamPortDefinition, &portdef));
  if(portdef.bEnabled != OMX_FALSE || portdef.nBufferCountActual == 0 || portdef.nBufferSize == 0)
    exit(3);

  omxdbg("Allocating buffers for %s:%d\n", oc->oc_name, port);
  omxdbg("  buffer count = %d\n", (int)portdef.nBufferCountActual);
  omxdbg("  buffer size  = %d\n", (int)portdef.nBufferSize);

  omx_send_command(oc, OMX_CommandPortEnable, port, NULL, 0);
  int i;
  for(i = 0; i < portdef.nBufferCountActual; i++) {
    OMX_BUFFERHEADERTYPE *buf;
    omxchk(OMX_AllocateBuffer(oc->oc_handle, &buf, port, NULL, portdef.nBufferSize));
    omxdbg("buf=%p\n", buf);
    buf->pAppPrivate = oc->oc_avail;
    oc->oc_avail = buf;
    oc->oc_avail_bytes += buf->nAllocLen;
  }
  omx_wait_command(oc); // Waits for the OMX_CommandPortEnable command

}
示例#3
0
文件: omx.c 项目: Ezio-PS/movian
void
omx_set_state(omx_component_t *oc, OMX_STATETYPE reqstate)
{
  OMX_STATETYPE state;
  int attempts = 20;
  omxchk(OMX_GetState(oc->oc_handle, &state));
  omxdbg("Telling component '%s' to go from state %d -> to state %d\n", oc->oc_name, state, reqstate);


  while(1) {
    oc->oc_cmd_done = 0;

    int r = OMX_SendCommand(oc->oc_handle, OMX_CommandStateSet,
                          reqstate, NULL);

    if(r == OMX_ErrorInsufficientResources && attempts) {
      usleep(10000);
      attempts--;
      continue;
    }

    if(r != 0) {
      panic("OMX Setstate %s from %d to %d error 0x%x",
            oc->oc_name, state, reqstate, r);
    }

    if(reqstate == OMX_StateExecuting)
      omx_wait_command(oc);

    return;
  }
}
示例#4
0
文件: omx.c 项目: Ezio-PS/movian
void
omx_send_command(omx_component_t *oc, OMX_COMMANDTYPE cmd, int v, void *p,
		 int wait)
{
  oc->oc_cmd_done = 0;

  omxdbg("%s: CMD(0x%x, 0x%x, %p)\n", oc->oc_name, cmd, v, p);

  omxchk(OMX_SendCommand(oc->oc_handle, cmd, v, p));

  if(wait)
    omx_wait_command(oc);
}
示例#5
0
static void
setup_tunnel(rpi_pixmap_decoder_t *rpd)
{
  int dst_width, dst_height;
  OMX_PARAM_PORTDEFINITIONTYPE portdef;

  if(rpd->rpd_tunnel != NULL)
    return;

  OMX_INIT_STRUCTURE(portdef);
  portdef.nPortIndex = rpd->rpd_decoder->oc_outport;
  omxchk(OMX_GetParameter(rpd->rpd_decoder->oc_handle,
			  OMX_IndexParamPortDefinition, &portdef));

  pixmap_compute_rescale_dim(rpd->rpd_im,
			     portdef.format.image.nFrameWidth,
			     portdef.format.image.nFrameHeight,
			     &dst_width, &dst_height);

  portdef.nPortIndex = rpd->rpd_resizer->oc_inport;
  omxchk(OMX_SetParameter(rpd->rpd_resizer->oc_handle,
			  OMX_IndexParamPortDefinition, &portdef));

  rpd->rpd_tunnel = omx_tunnel_create(rpd->rpd_decoder,
				      rpd->rpd_decoder->oc_outport,
				      rpd->rpd_resizer,
				      rpd->rpd_resizer->oc_inport,
				      "decoder -> resizer");
  OMX_INIT_STRUCTURE(portdef);

  portdef.nPortIndex = rpd->rpd_resizer->oc_outport;
  omxchk(OMX_GetParameter(rpd->rpd_resizer->oc_handle,
			  OMX_IndexParamPortDefinition, &portdef));

  int stride = (dst_width * 4 + PIXMAP_ROW_ALIGN - 1) & ~(PIXMAP_ROW_ALIGN - 1);

  portdef.format.image.eCompressionFormat    = OMX_IMAGE_CodingUnused;
  portdef.format.image.eColorFormat          = OMX_COLOR_Format32bitABGR8888;
  portdef.format.image.nFrameWidth           = dst_width;
  portdef.format.image.nFrameHeight          = dst_height;
  portdef.format.image.nStride               = stride;
  portdef.format.image.nSliceHeight          = 0;
  portdef.format.image.bFlagErrorConcealment = OMX_FALSE;

  omxchk(OMX_SetParameter(rpd->rpd_resizer->oc_handle,
			  OMX_IndexParamPortDefinition, &portdef));

  omxchk(OMX_GetParameter(rpd->rpd_resizer->oc_handle,
			  OMX_IndexParamPortDefinition, &portdef));

  omx_set_state(rpd->rpd_resizer, OMX_StateExecuting);
  omx_port_enable(rpd->rpd_resizer, rpd->rpd_resizer->oc_outport);

  pixmap_t *pm = rpd->rpd_pm = calloc(1, sizeof(pixmap_t));
  pm->pm_refcount = 1;
  pm->pm_width    = portdef.format.image.nFrameWidth;
  pm->pm_height   = portdef.format.image.nFrameHeight;
  pm->pm_linesize = portdef.format.image.nStride;
  pm->pm_type     = PIXMAP_BGR32;
  pm->pm_data     = mymemalign(portdef.nBufferAlignment, portdef.nBufferSize);
  pm->pm_aspect   = (float)pm->pm_width / (float)pm->pm_height;

  omxchk(OMX_UseBuffer(rpd->rpd_resizer->oc_handle, &rpd->rpd_buf,
		       rpd->rpd_resizer->oc_outport,
		       NULL, portdef.nBufferSize, pm->pm_data));

  omx_wait_command(rpd->rpd_resizer);
  omxchk(OMX_FillThisBuffer(rpd->rpd_resizer->oc_handle, rpd->rpd_buf));
}
示例#6
0
static pixmap_t *
rpi_pixmap_decode(pixmap_t *pm, const image_meta_t *im,
		  char *errbuf, size_t errlen)
{

  if(pm->pm_type != PIXMAP_JPEG)
    return NULL;

#ifdef TIMING
  int64_t ts = showtime_get_ts(), ts2;
#endif
  rpi_pixmap_decoder_t *rpd = pixmap_decoder_create(OMX_IMAGE_CodingJPEG);

  if(rpd == NULL)
    return NULL;
  rpd->rpd_im = im;

#ifdef NOCOPY


#error check rpd->rpd_decoder->oc_stream_corrupt

  OMX_PARAM_PORTDEFINITIONTYPE portdef;

  memset(&portdef, 0, sizeof(portdef));
  portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
  portdef.nVersion.nVersion = OMX_VERSION;
  portdef.nPortIndex = rpd->rpd_decoder->oc_inport;

  omxchk(OMX_GetParameter(rpd->rpd_decoder->oc_handle,
			  OMX_IndexParamPortDefinition, &portdef));

  omx_send_command(rpd->rpd_decoder, OMX_CommandPortEnable,
		   rpd->rpd_decoder->oc_inport, NULL, 0);

  OMX_BUFFERHEADERTYPE *buf;
  
  for(int i = 0; i < portdef.nBufferCountActual; i++) {
    omxchk(OMX_UseBuffer(rpd->rpd_decoder->oc_handle, &buf,
			 rpd->rpd_decoder->oc_inport, 
			 NULL, pm->pm_size, pm->pm_data));
  }

  // Waits for the OMX_CommandPortEnable command
  omx_wait_command(rpd->rpd_decoder);
  
  omx_set_state(rpd->rpd_decoder, OMX_StateExecuting);

  CHECKPOINT("Initialized");

  buf->nOffset = 0;
  buf->nFilledLen = pm->pm_size;

  buf->nFlags |= OMX_BUFFERFLAG_EOS;

  rpd->rpd_decoder->oc_inflight_buffers++;

  omxchk(OMX_EmptyThisBuffer(rpd->rpd_decoder->oc_handle, buf));
  
  hts_mutex_lock(&rpd->rpd_mtx);
  while(rpd->rpd_change == 0)
    hts_cond_wait(&rpd->rpd_cond, &rpd->rpd_mtx);
  hts_mutex_unlock(&rpd->rpd_mtx);
  CHECKPOINT("Setup tunnel");
  setup_tunnel(rpd);



#else

  const void *data = pm->pm_data;
  size_t len = pm->pm_size;



  hts_mutex_lock(&rpd->rpd_mtx);

  while(len > 0) {
    OMX_BUFFERHEADERTYPE *buf;

    if(rpd->rpd_decoder->oc_stream_corrupt)
      break;

    if(rpd->rpd_change == 1) {
      rpd->rpd_change = 2;
      hts_mutex_unlock(&rpd->rpd_mtx);
      setup_tunnel(rpd);
      hts_mutex_lock(&rpd->rpd_mtx);
      continue;
    }

    if(rpd->rpd_decoder->oc_avail == NULL) {
      hts_cond_wait(&rpd->rpd_cond, &rpd->rpd_mtx);
      continue;
    }

    buf = rpd->rpd_decoder->oc_avail;
    rpd->rpd_decoder->oc_avail = buf->pAppPrivate;
    rpd->rpd_decoder->oc_inflight_buffers++;

    hts_mutex_unlock(&rpd->rpd_mtx);

    buf->nOffset = 0;
    buf->nFilledLen = MIN(len, buf->nAllocLen);
    memcpy(buf->pBuffer, data, buf->nFilledLen);
    buf->nFlags = 0;

    if(len <= buf->nAllocLen)
      buf->nFlags |= OMX_BUFFERFLAG_EOS;

    data += buf->nFilledLen;
    len  -= buf->nFilledLen;
    omxchk(OMX_EmptyThisBuffer(rpd->rpd_decoder->oc_handle, buf));

    hts_mutex_lock(&rpd->rpd_mtx);
  }

  if(rpd->rpd_decoder->oc_stream_corrupt) {
    hts_mutex_unlock(&rpd->rpd_mtx);
    goto err;
  }

  if(rpd->rpd_change != 2) {
    while(rpd->rpd_change == 0 && !rpd->rpd_decoder->oc_stream_corrupt)
      hts_cond_wait(&rpd->rpd_cond, &rpd->rpd_mtx);

    

    hts_mutex_unlock(&rpd->rpd_mtx);
    if(rpd->rpd_decoder->oc_stream_corrupt)
      goto err;

    setup_tunnel(rpd);
  } else {
    hts_mutex_unlock(&rpd->rpd_mtx);
  }
#endif

  
  omx_wait_fill_buffer(rpd->rpd_resizer, rpd->rpd_buf);
  CHECKPOINT("Got buffer");

 err:
  omx_flush_port(rpd->rpd_decoder, rpd->rpd_decoder->oc_inport);
  omx_flush_port(rpd->rpd_decoder, rpd->rpd_decoder->oc_outport);

  omx_flush_port(rpd->rpd_resizer, rpd->rpd_resizer->oc_inport);
  omx_flush_port(rpd->rpd_resizer, rpd->rpd_resizer->oc_outport);



  if(rpd->rpd_tunnel != NULL) {
    omx_tunnel_destroy(rpd->rpd_tunnel);
    rpd->rpd_tunnel = NULL;
  }

  omx_set_state(rpd->rpd_decoder, OMX_StateIdle);
  omx_set_state(rpd->rpd_resizer, OMX_StateIdle);

  if(rpd->rpd_buf != NULL) {
    omxchk(OMX_FreeBuffer(rpd->rpd_resizer->oc_handle,
			  rpd->rpd_resizer->oc_outport, rpd->rpd_buf));
  }

  omx_release_buffers(rpd->rpd_decoder, rpd->rpd_decoder->oc_inport);

  omx_set_state(rpd->rpd_resizer, OMX_StateLoaded);
  omx_set_state(rpd->rpd_decoder, OMX_StateLoaded);

  omx_component_destroy(rpd->rpd_resizer);
  omx_component_destroy(rpd->rpd_decoder);
  hts_cond_destroy(&rpd->rpd_cond);
  hts_mutex_destroy(&rpd->rpd_mtx);

  pixmap_t *out = rpd->rpd_pm;
  if(out) {
    pixmap_release(pm);
  } else {
    snprintf(errbuf, errlen, "Load error");
  }

  free(rpd);
  CHECKPOINT("All done");
  return out;
}