static GstFlowReturn vorbis_handle_type_packet (GstVorbisDec * vd) { GList *walk; gint res; g_assert (vd->initialized == FALSE); #ifdef USE_TREMOLO if (G_UNLIKELY ((res = vorbis_dsp_init (&vd->vd, &vd->vi)))) goto synthesis_init_error; #else if (G_UNLIKELY ((res = vorbis_synthesis_init (&vd->vd, &vd->vi)))) goto synthesis_init_error; if (G_UNLIKELY ((res = vorbis_block_init (&vd->vd, &vd->vb)))) goto block_init_error; #endif vd->initialized = TRUE; if (vd->pendingevents) { for (walk = vd->pendingevents; walk; walk = g_list_next (walk)) gst_pad_push_event (vd->srcpad, GST_EVENT_CAST (walk->data)); g_list_free (vd->pendingevents); vd->pendingevents = NULL; } if (vd->taglist) { /* The tags have already been sent on the bus as messages. */ gst_pad_push_event (vd->srcpad, gst_event_new_tag (vd->taglist)); vd->taglist = NULL; } return GST_FLOW_OK; /* ERRORS */ synthesis_init_error: { GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE, (NULL), ("couldn't initialize synthesis (%d)", res)); return GST_FLOW_ERROR; } block_init_error: { GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE, (NULL), ("couldn't initialize block (%d)", res)); return GST_FLOW_ERROR; } }
static GstFlowReturn vorbis_handle_type_packet (GstVorbisDec * vd) { gint res; g_assert (vd->initialized == FALSE); #ifdef USE_TREMOLO if (G_UNLIKELY ((res = vorbis_dsp_init (&vd->vd, &vd->vi)))) goto synthesis_init_error; #else if (G_UNLIKELY ((res = vorbis_synthesis_init (&vd->vd, &vd->vi)))) goto synthesis_init_error; if (G_UNLIKELY ((res = vorbis_block_init (&vd->vd, &vd->vb)))) goto block_init_error; #endif vd->initialized = TRUE; return GST_FLOW_OK; /* ERRORS */ synthesis_init_error: { GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE, (NULL), ("couldn't initialize synthesis (%d)", res)); return GST_FLOW_ERROR; } block_init_error: { GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE, (NULL), ("couldn't initialize block (%d)", res)); return GST_FLOW_ERROR; } }
void SoftVorbis::onQueueFilled(OMX_U32 portIndex) { List<BufferInfo *> &inQueue = getPortQueue(0); List<BufferInfo *> &outQueue = getPortQueue(1); if (mOutputPortSettingsChange != NONE) { return; } if (portIndex == 0 && mInputBufferCount < 2) { BufferInfo *info = *inQueue.begin(); OMX_BUFFERHEADERTYPE *header = info->mHeader; const uint8_t *data = header->pBuffer + header->nOffset; size_t size = header->nFilledLen; ogg_buffer buf; ogg_reference ref; oggpack_buffer bits; makeBitReader( (const uint8_t *)data + 7, size - 7, &buf, &ref, &bits); if (mInputBufferCount == 0) { CHECK(mVi == NULL); mVi = new vorbis_info; vorbis_info_init(mVi); CHECK_EQ(0, _vorbis_unpack_info(mVi, &bits)); } else { CHECK_EQ(0, _vorbis_unpack_books(mVi, &bits)); CHECK(mState == NULL); mState = new vorbis_dsp_state; CHECK_EQ(0, vorbis_dsp_init(mState, mVi)); notify(OMX_EventPortSettingsChanged, 1, 0, NULL); mOutputPortSettingsChange = AWAITING_DISABLED; } inQueue.erase(inQueue.begin()); info->mOwnedByUs = false; notifyEmptyBufferDone(header); ++mInputBufferCount; return; } while (!inQueue.empty() && !outQueue.empty()) { BufferInfo *inInfo = *inQueue.begin(); OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; BufferInfo *outInfo = *outQueue.begin(); OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { inQueue.erase(inQueue.begin()); inInfo->mOwnedByUs = false; notifyEmptyBufferDone(inHeader); outHeader->nFilledLen = 0; outHeader->nFlags = OMX_BUFFERFLAG_EOS; outQueue.erase(outQueue.begin()); outInfo->mOwnedByUs = false; notifyFillBufferDone(outHeader); return; } int32_t numPageSamples; CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples)); memcpy(&numPageSamples, inHeader->pBuffer + inHeader->nOffset + inHeader->nFilledLen - 4, sizeof(numPageSamples)); if (numPageSamples >= 0) { mNumFramesLeftOnPage = numPageSamples; } if (inHeader->nOffset == 0) { mAnchorTimeUs = inHeader->nTimeStamp; mNumFramesOutput = 0; } inHeader->nFilledLen -= sizeof(numPageSamples);; ogg_buffer buf; buf.data = inHeader->pBuffer + inHeader->nOffset; buf.size = inHeader->nFilledLen; buf.refcount = 1; buf.ptr.owner = NULL; ogg_reference ref; ref.buffer = &buf; ref.begin = 0; ref.length = buf.size; ref.next = NULL; ogg_packet pack; pack.packet = &ref; pack.bytes = ref.length; pack.b_o_s = 0; pack.e_o_s = 0; pack.granulepos = 0; pack.packetno = 0; int numFrames = 0; int err = vorbis_dsp_synthesis(mState, &pack, 1); if (err != 0) { ALOGW("vorbis_dsp_synthesis returned %d", err); } else { numFrames = vorbis_dsp_pcmout( mState, (int16_t *)outHeader->pBuffer, kMaxNumSamplesPerBuffer); if (numFrames < 0) { ALOGE("vorbis_dsp_pcmout returned %d", numFrames); numFrames = 0; } } if (mNumFramesLeftOnPage >= 0) { if (numFrames > mNumFramesLeftOnPage) { ALOGV("discarding %d frames at end of page", numFrames - mNumFramesLeftOnPage); numFrames = mNumFramesLeftOnPage; } mNumFramesLeftOnPage -= numFrames; } outHeader->nFilledLen = numFrames * sizeof(int16_t) * mVi->channels; outHeader->nOffset = 0; outHeader->nFlags = 0; outHeader->nTimeStamp = mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mVi->rate; mNumFramesOutput += numFrames; inInfo->mOwnedByUs = false; inQueue.erase(inQueue.begin()); inInfo = NULL; notifyEmptyBufferDone(inHeader); inHeader = NULL; outInfo->mOwnedByUs = false; outQueue.erase(outQueue.begin()); outInfo = NULL; notifyFillBufferDone(outHeader); outHeader = NULL; ++mInputBufferCount; } }