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; }
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; }
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; }