static void reset_stream_parameters (vorbisd_prc_t *ap_prc)
{
  assert (NULL != ap_prc);
  ap_prc->started_ = false;
  tiz_mem_set (&(ap_prc->fsinfo_), 0, sizeof(FishSoundInfo));
  tiz_filter_prc_update_eos_flag (ap_prc, false);
}
static void
propagate_eos_if_required (mp4dmuxflt_prc_t * ap_prc,
                           OMX_BUFFERHEADERTYPE * ap_out_hdr)
{
  assert (ap_prc);
  assert (ap_out_hdr);

  /* If EOS, propagate the flag to the next component */
  if (tiz_filter_prc_is_eos (ap_prc)
      && tiz_buffer_available (ap_prc->p_mp4_store_) == 0)
    {
      ap_out_hdr->nFlags |= OMX_BUFFERFLAG_EOS;
      tiz_filter_prc_update_eos_flag (ap_prc, false);
    }
}
/* TODO: move this functionality to tiz_filter_prc_t */
static OMX_ERRORTYPE
release_input_header (mp4dmuxflt_prc_t * ap_prc)
{
  OMX_ERRORTYPE rc = OMX_ErrorNone;
  OMX_BUFFERHEADERTYPE * p_hdr = get_mp4_hdr (ap_prc);

  assert (ap_prc);

  if (p_hdr)
    {
      TIZ_DEBUG (handleOf (ap_prc), "[%p] nFlags [%d]", p_hdr, p_hdr->nFlags);
      if ((p_hdr->nFlags & OMX_BUFFERFLAG_EOS) > 0)
        {
          tiz_filter_prc_update_eos_flag (ap_prc, true);
          p_hdr->nFlags &= ~(1 << OMX_BUFFERFLAG_EOS);
        }
      rc = tiz_filter_prc_release_header (
        ap_prc, ARATELIA_MP4_DEMUXER_FILTER_PORT_0_INDEX);
    }
  return rc;
}
Exemple #4
0
static OMX_ERRORTYPE
transform_buffer (fr_prc_t *ap_prc)
{
  OMX_ERRORTYPE rc = OMX_ErrorNone;
  OMX_BUFFERHEADERTYPE *p_in
      = tiz_filter_prc_get_header (ap_prc, ARATELIA_FILE_READER_INPUT_PORT_INDEX);
  OMX_BUFFERHEADERTYPE *p_out
      = tiz_filter_prc_get_header (ap_prc, ARATELIA_FILE_READER_OUTPUT_PORT_INDEX);

  if (NULL == p_in || NULL == p_out)
    {
      TIZ_TRACE (handleOf (ap_prc), "IN HEADER [%p] OUT HEADER [%p]", p_in,
                 p_out);
      return OMX_ErrorNone;
    }

  assert (ap_prc);

  if (0 == p_in->nFilledLen)
    {
      TIZ_TRACE (handleOf (ap_prc), "HEADER [%p] nFlags [%d] is empty", p_in,
                 p_in->nFlags);
      if ((p_in->nFlags & OMX_BUFFERFLAG_EOS) > 0)
        {
          /* Inmediately propagate EOS flag to output */
          TIZ_TRACE (handleOf (ap_prc), "Propagate EOS flag to output HEADER [%p]",
                     p_out);
          p_out->nFlags |= OMX_BUFFERFLAG_EOS;
          tiz_filter_prc_update_eos_flag (ap_prc, true);
          p_in->nFlags   = 0;
          tiz_check_omx
            (tiz_filter_prc_release_header (ap_prc, ARATELIA_FILE_READER_OUTPUT_PORT_INDEX));
        }
    }

  return rc;
}
Exemple #5
0
static void reset_stream_parameters (fr_prc_t *ap_prc)
{
  assert (ap_prc);
  tiz_filter_prc_update_eos_flag (ap_prc, false);
}
static OMX_ERRORTYPE transform_buffer (vorbisd_prc_t *ap_prc)
{
  OMX_ERRORTYPE rc = OMX_ErrorNone;
  OMX_BUFFERHEADERTYPE *p_in
    = tiz_filter_prc_get_header
    (ap_prc, ARATELIA_VORBIS_DECODER_INPUT_PORT_INDEX);
  OMX_BUFFERHEADERTYPE *p_out
    = tiz_filter_prc_get_header
    (ap_prc, ARATELIA_VORBIS_DECODER_OUTPUT_PORT_INDEX);

  if (NULL == p_in || NULL == p_out)
    {
      TIZ_TRACE (handleOf (ap_prc), "IN HEADER [%p] OUT HEADER [%p]", p_in,
                 p_out);
      return OMX_ErrorNone;
    }

  assert (NULL != ap_prc);

  if (0 == p_in->nFilledLen)
    {
      TIZ_TRACE (handleOf (ap_prc), "HEADER [%p] nFlags [%d] is empty", p_in,
                 p_in->nFlags);
      if ((p_in->nFlags & OMX_BUFFERFLAG_EOS) > 0)
        {
          /* Inmediately propagate EOS flag to output */
          TIZ_TRACE (handleOf (ap_prc), "Let's propagate EOS flag to output");
          p_out->nFlags |= OMX_BUFFERFLAG_EOS;
          p_in->nFlags &= ~(1 << OMX_BUFFERFLAG_EOS);
          tiz_check_omx_err
            (tiz_filter_prc_release_header
            (ap_prc, ARATELIA_VORBIS_DECODER_OUTPUT_PORT_INDEX));
        }
    }

  if (p_in->nFilledLen > 0)
    {
      unsigned char *p_data = p_in->pBuffer + p_in->nOffset;
      const long len = p_in->nFilledLen;
      long bytes_consumed = fish_sound_decode (ap_prc->p_fsnd_, p_data, len);
      TIZ_TRACE (handleOf (ap_prc), "p_in->nFilledLen [%d] ", p_in->nFilledLen);
      TIZ_TRACE (handleOf (ap_prc), "bytes_consumed [%d] ", bytes_consumed);

      if (bytes_consumed >= 0)
        {
          assert (p_in->nFilledLen >= bytes_consumed);
          p_in->nFilledLen = 0;
          p_in->nOffset = 0;
        }
      else
        {
          switch (bytes_consumed)
            {
              case FISH_SOUND_STOP_ERR:
                {
                  /* Decoding was stopped by a FishSoundDecode* */
                  /* callback returning FISH_SOUND_STOP_ERR before any input
                   * bytes were consumed. */
                  /* This will occur when PCM is decoded from previously
                   * buffered input, and */
                  /* stopping is immediately requested. */
                  TIZ_ERROR (handleOf (ap_prc),
                             "[FISH_SOUND_ERR_STOP_ERR] : "
                             "While decoding the input stream.");
                  rc = OMX_ErrorStreamCorruptFatal;
                }
                break;
              case FISH_SOUND_ERR_OUT_OF_MEMORY:
                {
                  TIZ_ERROR (handleOf (ap_prc),
                             "[FISH_SOUND_ERR_OUT_OF_MEMORY] : "
                             "While decoding the input stream.");
                  rc = OMX_ErrorInsufficientResources;
                }
                break;
              case FISH_SOUND_ERR_BAD:
                {
                  TIZ_ERROR (handleOf (ap_prc),
                             "[FISH_SOUND_ERR_BAD] : "
                             "While decoding the input stream.");
                  rc = OMX_ErrorStreamCorruptFatal;
                }
                break;
              default:
                {
                  TIZ_ERROR (handleOf (ap_prc),
                             "[%s] : "
                             "While decoding the input stream.",
                             bytes_consumed);
                  assert (0);
                  rc = OMX_ErrorStreamCorruptFatal;
                }
            };
        }
    }

  assert (p_in->nFilledLen >= 0);

  if (0 == p_in->nFilledLen)
    {
      TIZ_TRACE (handleOf (ap_prc), "HEADER [%p] nFlags [%d] is empty", p_in,
                 p_in->nFlags);
      if ((p_in->nFlags & OMX_BUFFERFLAG_EOS) > 0)
        {
          /* Let's propagate EOS flag to output */
          TIZ_TRACE (handleOf (ap_prc), "Let's propagate EOS flag to output");
          tiz_filter_prc_update_eos_flag (ap_prc, true);
          p_in->nFlags &= ~(1 << OMX_BUFFERFLAG_EOS);
        }
      rc = tiz_filter_prc_release_header
        (ap_prc, ARATELIA_VORBIS_DECODER_INPUT_PORT_INDEX);
    }

  return rc;
}
static int fishsound_decoded_callback (FishSound *ap_fsound, float *app_pcm[],
                                       long frames, void *ap_user_data)
{
  int rc = FISH_SOUND_CONTINUE;
  vorbisd_prc_t *p_prc = ap_user_data;
  OMX_BUFFERHEADERTYPE *p_out = NULL;

  (void)ap_fsound;
  assert (NULL != app_pcm);
  assert (NULL != ap_user_data);

  TIZ_TRACE (handleOf (p_prc), "frames [%d] ", frames);

  /* Possible return values are: */

  /* FISH_SOUND_CONTINUE Continue decoding */
  /* FISH_SOUND_STOP_OK Stop decoding immediately and return control to the
     fish_sound_decode() caller */
  /* FISH_SOUND_STOP_ERR Stop decoding immediately, purge buffered data, and
     return control to the fish_sound_decode() caller */

  if (!p_prc->started_)
    {
      p_prc->started_ = true;
      fish_sound_command (p_prc->p_fsnd_, FISH_SOUND_GET_INFO,
                          &(p_prc->fsinfo_), sizeof(FishSoundInfo));
      if (p_prc->fsinfo_.channels > 2 || p_prc->fsinfo_.format
                                         != FISH_SOUND_VORBIS)
        {
          TIZ_ERROR (handleOf (p_prc),
                     "Supported Vorbis "
                     "streams up tp 2 channels only.");
          rc = FISH_SOUND_STOP_ERR;
          goto end;
        }
      TIZ_NOTICE (handleOf (p_prc), "Channels [%d] sampling rate [%d]",
                  p_prc->fsinfo_.channels, p_prc->fsinfo_.samplerate);
    }

  p_out = tiz_filter_prc_get_header (p_prc, ARATELIA_VORBIS_DECODER_OUTPUT_PORT_INDEX);
  if (NULL == p_out)
    {
      TIZ_TRACE (handleOf (p_prc),
                 "No more output buffers "
                 "available at the moment");
      rc = FISH_SOUND_STOP_OK;
      goto end;
    }

  {
    /* write decoded PCM samples */
    size_t i = 0;
    size_t frame_len = sizeof(float) * p_prc->fsinfo_.channels;
    size_t frames_alloc = ((p_out->nAllocLen - p_out->nOffset) / frame_len);
    size_t frames_to_write = (frames > frames_alloc) ? frames_alloc : frames;
    size_t bytes_to_write = frames_to_write * frame_len;
    assert (NULL != p_out);

    for (i = 0; i < frames_to_write; ++i)
      {
        size_t frame_offset = i * frame_len;
        size_t float_offset = i * p_prc->fsinfo_.channels;
        float *out = (float *)(p_out->pBuffer + p_out->nOffset + frame_offset);
        write_frame_float_ilv (out, ((float *)app_pcm) + float_offset,
                               p_prc->fsinfo_.channels);
      }
    p_out->nFilledLen += bytes_to_write;
    p_out->nOffset += bytes_to_write;

    if (frames_to_write < frames)
      {
        /* Temporarily store the data until an omx buffer is
         * available */
        OMX_U32 nbytes_remaining = (frames - frames_to_write) * frame_len;
        TIZ_TRACE (handleOf (p_prc), "Need to store [%d] bytes",
                   nbytes_remaining);
        nbytes_remaining = store_data (
            p_prc, (OMX_U8 *)(app_pcm[frames_to_write * sizeof(float)]),
            nbytes_remaining);
      }

    if (tiz_filter_prc_is_eos (p_prc))
      {
        /* Propagate EOS flag to output */
        p_out->nFlags |= OMX_BUFFERFLAG_EOS;
        tiz_filter_prc_update_eos_flag (p_prc, false);
        TIZ_TRACE (handleOf (p_prc), "Propagating EOS flag to output");
      }
    /* TODO: Shouldn't ignore this rc */
    (void)tiz_filter_prc_release_header
      (p_prc, ARATELIA_VORBIS_DECODER_OUTPUT_PORT_INDEX);
    /* Let's process one input buffer at a time, for now */
    rc = FISH_SOUND_STOP_OK;
  }

end:

  return rc;
}