示例#1
0
文件: omx.c 项目: Ezio-PS/movian
omx_tunnel_t *
omx_tunnel_create(omx_component_t *src, int srcport, omx_component_t *dst,
		  int dstport, const char *name)
{
  OMX_STATETYPE state;
  omxchk(OMX_GetState(src->oc_handle, &state));

  if(state == OMX_StateLoaded)
    omx_set_state(src, OMX_StateIdle);

  omxdbg("Creating tunnel %s from %s:%d to %s:%d\n",
	 name, src->oc_name, srcport, dst->oc_name, dstport);

  omx_send_command(src, OMX_CommandPortDisable, srcport, NULL, 1);
  omx_send_command(dst, OMX_CommandPortDisable, dstport, NULL, 1);
  omxchk(OMX_SetupTunnel(src->oc_handle, srcport, dst->oc_handle, dstport));
  omx_send_command(src, OMX_CommandPortEnable, srcport, NULL, 0);
  omx_send_command(dst, OMX_CommandPortEnable, dstport, NULL, 0);

  omxchk(OMX_GetState(dst->oc_handle, &state));
  if(state == OMX_StateLoaded)
    omx_set_state(dst, OMX_StateIdle);

  omx_tunnel_t *ot = malloc(sizeof(omx_tunnel_t));
  ot->ot_src = src;
  ot->ot_srcport = srcport;
  ot->ot_dst = dst;
  ot->ot_dstport = dstport;
  ot->ot_name = name;
  return ot;
}
示例#2
0
文件: omx.c 项目: kshostak/showtime
void
omx_tunnel_destroy(omx_tunnel_t *ot)
{
  omxdbg("Destroying tunnel\n");
  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);
  omxchk(OMX_SetupTunnel(ot->ot_src->oc_handle, ot->ot_srcport, NULL, 0));
  free(ot);
}
示例#3
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

}
示例#4
0
文件: omx.c 项目: kshostak/showtime
void
omx_set_state(omx_component_t *oc, OMX_STATETYPE reqstate)
{
  OMX_STATETYPE state;

  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);
  omx_send_command(oc, OMX_CommandStateSet, reqstate, NULL, reqstate != OMX_StateLoaded);
}
示例#5
0
文件: omx.c 项目: Ezio-PS/movian
omx_component_t *
omx_component_create(const char *name, hts_mutex_t *mtx,
                     hts_cond_t *avail_cond)
{
  omx_component_t *oc = calloc(1, sizeof(omx_component_t));
  OMX_CALLBACKTYPE cb;
  const OMX_INDEXTYPE types[] = {OMX_IndexParamAudioInit,
                                 OMX_IndexParamVideoInit,
                                 OMX_IndexParamImageInit,
                                 OMX_IndexParamOtherInit};

  assert(mtx != NULL);
  oc->oc_mtx = mtx;

  oc->oc_avail_cond = avail_cond;

  hts_cond_init(&oc->oc_event_cond, oc->oc_mtx);

  oc->oc_name = strdup(name);

  cb.EventHandler    = oc_event_handler;
  cb.EmptyBufferDone = oc_empty_buffer_done;
  cb.FillBufferDone  = oc_fill_buffer_done;

  //  omxdbg("Creating %s\n", oc->oc_name);
  omxchk(OMX_GetHandle(&oc->oc_handle, oc->oc_name, oc, &cb));

  // Initially disable ports
  int i;
  for(i = 0; i < 4; i++) {
    OMX_PORT_PARAM_TYPE ports;
    ports.nSize = sizeof(OMX_PORT_PARAM_TYPE);
    ports.nVersion.nVersion = OMX_VERSION;

    omxchk(OMX_GetParameter(oc->oc_handle, types[i], &ports));
    omxdbg("%s: type:%d: ports: %d +%d\n", name, i, ports.nStartPortNumber, ports.nPorts);

    if(ports.nPorts > 0) {
      oc->oc_inport = ports.nStartPortNumber;
      oc->oc_outport = ports.nStartPortNumber + 1;
    }

    for(int j = 0; j < ports.nPorts; j++)
      omx_send_command(oc, OMX_CommandPortDisable, ports.nStartPortNumber + j, NULL, 1);

  }


  return oc;
}
示例#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;
}
示例#7
0
文件: omx.c 项目: Ezio-PS/movian
void
omx_flush_port(omx_component_t *oc, int port)
{
  omx_send_command(oc, OMX_CommandFlush, port, NULL, 1);
}
示例#8
0
文件: omx.c 项目: Ezio-PS/movian
void
omx_port_enable(omx_component_t *c, int port)
{
  omx_send_command(c, OMX_CommandPortEnable, port, NULL, 0);
}
示例#9
0
文件: omx.c 项目: dev-life/showtime
void
omx_flush_port(omx_component_t *oc, int port)
{
  printf("Flushing %s %d\n", oc->oc_name, port);
  omx_send_command(oc, OMX_CommandFlush, port, NULL, 1);
}