static int
flush_temp_store (oggdmux_prc_t * ap_prc, const OMX_U32 a_pid)
{
  OMX_BUFFERHEADERTYPE * p_hdr = NULL;
  OMX_U32 * p_offset = get_store_offset_ptr (ap_prc, a_pid);
  OMX_U32 ds_offset = *p_offset;

  assert (p_offset);

  if (0 == *p_offset)
    {
      /* The temp store is empty */
      return 0;
    }

  while ((p_hdr = get_header (ap_prc, a_pid)))
    {
      ds_offset = dump_temp_store (ap_prc, a_pid, p_hdr);
#ifdef _DEBUG
      if (a_pid == ARATELIA_OGG_DEMUXER_AUDIO_PORT_BASE_INDEX)
        {
          g_total_released += p_hdr->nFilledLen;
          OMX_U32 * p_offset = get_store_offset_ptr (ap_prc, a_pid);
          TIZ_TRACE (handleOf (ap_prc),
                     "total released [%d] "
                     "total read [%d] store [%d] last read [%d] diff [%d]",
                     g_total_released, g_total_read, *p_offset, g_last_read,
                     g_total_read - (g_total_released + *p_offset));
        }
#endif
      if (ap_prc->file_eos_ && 0 == ds_offset)
        {
          bool * p_eos = get_eos_ptr (ap_prc, a_pid);
          if (!p_eos)
            {
              TIZ_DEBUG (handleOf (ap_prc), "Adding EOS flag - PID [%d]",
                         a_pid);
              p_hdr->nFlags |= OMX_BUFFERFLAG_EOS;
              *p_eos = true;
            }
        }
      release_header (ap_prc, a_pid);
      p_hdr = 0;
      if (0 == ds_offset)
        {
          break;
        }
    }
  return ds_offset;
}
static int
read_packet (OGGZ * ap_oggz, oggz_packet * ap_zp, long serialno,
             void * ap_user_data, const OMX_U32 a_pid)
{
  oggdmux_prc_t * p_prc = ap_user_data;
  OMX_U32 op_offset = 0;
  bool * p_eos = NULL;
  ogg_packet * p_op = NULL;
  int rc = OGGZ_CONTINUE;

  assert (ap_oggz);
  assert (ap_zp);
  assert (p_prc);
  assert (a_pid <= ARATELIA_OGG_DEMUXER_VIDEO_PORT_BASE_INDEX);

  p_op = &(ap_zp->op);
  p_eos = get_eos_ptr (p_prc, a_pid);

  TIZ_TRACE (handleOf (p_prc), "%010lu: pid [%d] reading bytes [%d]", serialno,
             a_pid, p_op->bytes);

#ifdef _DEBUG
  if (a_pid == ARATELIA_OGG_DEMUXER_AUDIO_PORT_BASE_INDEX)
    {
      g_total_read += p_op->bytes;
      g_last_read = p_op->bytes;
    }
#endif

  if (oggz_get_eos (ap_oggz, serialno) == 1)
    {
      TIZ_TRACE (handleOf (p_prc), "%010lu: This is EOS\n", serialno);
      *p_eos = true;
    }

  /* Try to empty the ogg packet out to an omx buffer */
  op_offset = flush_ogg_packet (p_prc, a_pid, p_op->packet, p_op->bytes);

  if (0 == op_offset)
    {
      if (*p_eos || !get_header (p_prc, a_pid)
          || (*get_store_offset_ptr (p_prc, a_pid)) > 0)
        {
          rc = OGGZ_STOP_OK;
        }
      else
        {
          rc = OGGZ_CONTINUE;
        }
    }
  else /* (op_offset != 0) */
    {
      rc = OGGZ_STOP_ERR;
    }

  TIZ_TRACE (handleOf (p_prc), "%010lu: rc [%d] op_offset [%d]", serialno, rc,
             op_offset);

  return rc;
}
static int
flush_ogg_packet (oggdmux_prc_t * ap_prc, const OMX_U32 a_pid,
                  const OMX_U8 * ap_ogg_data, const OMX_U32 nbytes)
{
  OMX_BUFFERHEADERTYPE * p_hdr = NULL;
  OMX_U32 nbytes_remaining = nbytes;
  OMX_U32 nbytes_copied = 0;
  OMX_U32 op_offset = 0;

  while ((p_hdr = get_header (ap_prc, a_pid)))
    {
      nbytes_copied = dump_ogg_data (ap_prc, a_pid, ap_ogg_data + op_offset,
                                     nbytes_remaining, p_hdr);
      nbytes_remaining -= nbytes_copied;
      op_offset += nbytes_copied;
#ifdef _DEBUG
      if (a_pid == ARATELIA_OGG_DEMUXER_AUDIO_PORT_BASE_INDEX)
        {
          g_total_released += p_hdr->nFilledLen;
          OMX_U32 * p_offset = get_store_offset_ptr (ap_prc, a_pid);
          TIZ_TRACE (handleOf (ap_prc),
                     "total released [%d] "
                     "total read [%d] store [%d] last read [%d] "
                     "remaining [%d] diff [%d]",
                     g_total_released, g_total_read, *p_offset, g_last_read,
                     nbytes_remaining,
                     g_total_read - (g_total_released + nbytes_remaining));
        }
#endif
      release_header (ap_prc, a_pid);
      p_hdr = 0;
      if (0 == nbytes_remaining)
        {
          break;
        }
    }

  if (nbytes_remaining > 0)
    {
      /* Need_more_buffers. Temporarily store the data until an omx buffer is
       * available */
      TIZ_TRACE (handleOf (ap_prc), "Need to store [%d] bytes - pid [%d]",
                 nbytes_remaining, a_pid);
      nbytes_remaining
        = store_data (ap_prc, a_pid, ap_ogg_data + op_offset, nbytes_remaining);
    }

  return nbytes_remaining;
}
static int
store_data (oggdmux_prc_t * ap_prc, const OMX_U32 a_pid, const OMX_U8 * ap_data,
            OMX_U32 a_nbytes)
{
  OMX_U8 ** pp_store = NULL;
  OMX_U32 * p_offset = NULL;
  OMX_U32 * p_size = NULL;
  OMX_U32 nbytes_to_copy = 0;
  OMX_U32 nbytes_avail = 0;

  assert (ap_prc);
  assert (a_pid <= ARATELIA_OGG_DEMUXER_VIDEO_PORT_BASE_INDEX);
  assert (ap_data);

  pp_store = get_store_ptr (ap_prc, a_pid);
  p_size = get_store_size_ptr (ap_prc, a_pid);
  p_offset = get_store_offset_ptr (ap_prc, a_pid);

  assert (pp_store && *pp_store);
  assert (p_size);
  assert (p_offset);

  nbytes_avail = *p_size - *p_offset;

  if (a_nbytes > nbytes_avail)
    {
      /* need to re-alloc */
      OMX_U8 * p_new_store = NULL;
      p_new_store = tiz_mem_realloc (*pp_store, *p_offset + a_nbytes);
      if (p_new_store)
        {
          *pp_store = p_new_store;
          *p_size = *p_offset + a_nbytes;
          nbytes_avail = *p_size - *p_offset;
          TIZ_TRACE (handleOf (ap_prc),
                     "pid [%d] : Realloc'd data store "
                     "to new size [%d]",
                     a_pid, *p_size);
        }
    }
  nbytes_to_copy = MIN (nbytes_avail, a_nbytes);
  memcpy (*pp_store + *p_offset, ap_data, nbytes_to_copy);
  *p_offset += nbytes_to_copy;

  TIZ_TRACE (handleOf (ap_prc), "pid [%d]: bytes currently stored [%d]", a_pid,
             *p_offset);

  return a_nbytes - nbytes_to_copy;
}
static int store_data (vorbisd_prc_t *ap_prc, const OMX_U8 *ap_data,
                       OMX_U32 a_nbytes)
{
  OMX_U8 **pp_store = NULL;
  OMX_U32 *p_offset = NULL;
  OMX_U32 *p_size = NULL;
  OMX_U32 nbytes_to_copy = 0;
  OMX_U32 nbytes_avail = 0;

  assert (NULL != ap_prc);
  assert (NULL != ap_data);

  pp_store = get_store_ptr (ap_prc);
  p_size = get_store_size_ptr (ap_prc);
  p_offset = get_store_offset_ptr (ap_prc);

  assert (NULL != pp_store && NULL != *pp_store);
  assert (NULL != p_size);
  assert (NULL != p_offset);

  nbytes_avail = *p_size - *p_offset;

  if (a_nbytes > nbytes_avail)
    {
      /* need to re-alloc */
      OMX_U8 *p_new_store = NULL;
      p_new_store = tiz_mem_realloc (*pp_store, *p_offset + a_nbytes);
      if (NULL != p_new_store)
        {
          *pp_store = p_new_store;
          *p_size = *p_offset + a_nbytes;
          nbytes_avail = *p_size - *p_offset;
          TIZ_TRACE (handleOf (ap_prc),
                     "Realloc'd data store "
                     "to new size [%d]",
                     *p_size);
        }
    }
  nbytes_to_copy = MIN (nbytes_avail, a_nbytes);
  memcpy (*pp_store + *p_offset, ap_data, nbytes_to_copy);
  *p_offset += nbytes_to_copy;

  TIZ_TRACE (handleOf (ap_prc), "bytes currently stored [%d]", *p_offset);

  return a_nbytes - nbytes_to_copy;
}
static int
dump_temp_store (oggdmux_prc_t * ap_prc, const OMX_U32 a_pid,
                 OMX_BUFFERHEADERTYPE * ap_hdr)
{
  OMX_U8 * p_store = NULL;
  OMX_U32 * p_offset = NULL;
  OMX_U32 nbytes_to_copy = 0;
  OMX_U32 nbytes_avail = 0;

  assert (ap_prc);
  assert (a_pid <= ARATELIA_OGG_DEMUXER_VIDEO_PORT_BASE_INDEX);
  assert (ap_hdr);

  p_store = *(get_store_ptr (ap_prc, a_pid));
  p_offset = get_store_offset_ptr (ap_prc, a_pid);

  assert (p_store);
  assert (p_offset);
  assert (ap_hdr->nAllocLen >= ap_hdr->nFilledLen);

  nbytes_avail = ap_hdr->nAllocLen - ap_hdr->nFilledLen;
  nbytes_to_copy = MIN (*p_offset, nbytes_avail);

  if (nbytes_to_copy > 0)
    {
      memcpy (ap_hdr->pBuffer + ap_hdr->nFilledLen, p_store, nbytes_to_copy);
      ap_hdr->nFilledLen += nbytes_to_copy;
      *p_offset -= nbytes_to_copy;
      if (*p_offset > 0)
        {
          memmove (p_store, p_store + nbytes_to_copy, *p_offset);
        }
      TIZ_TRACE (handleOf (ap_prc),
                 "HEADER [%p] pid [%d] nFilledLen [%d] "
                 "offset [%d]",
                 ap_hdr, a_pid, ap_hdr->nFilledLen, *p_offset);
    }

  return *p_offset;
}