+
+ memcpy(mCtx->extradata + orig_extradata_size,
+ inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
+ memset(mCtx->extradata + mCtx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ }
+ }
+
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+
+ return ERR_OK;
+}
+
+int32_t SoftFFmpegAudio::openDecoder() {
+ if (mCodecAlreadyOpened) {
+ return ERR_OK;
+ }
+
+ if (!mExtradataReady && !mIgnoreExtradata) {
+ ALOGI("extradata is ready, size: %d", mCtx->extradata_size);
+ hexdump(mCtx->extradata, mCtx->extradata_size);
+ mExtradataReady = true;
+ }
+
+ //find decoder
+ mCtx->codec = avcodec_find_decoder(mCtx->codec_id);
+ if (!mCtx->codec) {
+ ALOGE("ffmpeg audio decoder failed to find codec");
+ return ERR_CODEC_NOT_FOUND;
+ }
+
+ CHECK(isConfigured());
+
+ setDefaultCtx(mCtx, mCtx->codec);
+
+ ALOGD("begin to open ffmpeg audio decoder(%s), mCtx sample_rate: %d, "
+ "channels: %d, , sample_fmt: %s",
+ avcodec_get_name(mCtx->codec_id),
+ mCtx->sample_rate, mCtx->channels,
+ av_get_sample_fmt_name(mCtx->sample_fmt));
+
+ int err = avcodec_open2(mCtx, mCtx->codec, NULL);
+ if (err < 0) {
+ ALOGE("ffmpeg audio decoder failed to initialize.(%s)", av_err2str(err));
+ return ERR_DECODER_OPEN_FAILED;
+ }
+ mCodecAlreadyOpened = true;
+
+ ALOGD("open ffmpeg audio decoder(%s) success, mCtx sample_rate: %d, "
+ "channels: %d, sample_fmt: %s",
+ avcodec_get_name(mCtx->codec_id),
+ mCtx->sample_rate, mCtx->channels,
+ av_get_sample_fmt_name(mCtx->sample_fmt));
+
+ mFrame = avcodec_alloc_frame();
+ if (!mFrame) {
+ ALOGE("oom for video frame");
+ return ERR_OOM;
+ }
+
+ return ERR_OK;
+}
+
+void SoftFFmpegAudio::updateTimeStamp(OMX_BUFFERHEADERTYPE *inHeader) {
+ CHECK_EQ(mInputBufferSize, 0);
+
+ //XXX reset to AV_NOPTS_VALUE if the pts is invalid
+ if (inHeader->nTimeStamp == SF_NOPTS_VALUE) {
+ inHeader->nTimeStamp = AV_NOPTS_VALUE;
+ }
+
+ //update the audio clock if the pts is valid
+ if (inHeader->nTimeStamp != AV_NOPTS_VALUE) {
+ mAudioClock = inHeader->nTimeStamp;
+ }
+}
+
+void SoftFFmpegAudio::initPacket(AVPacket *pkt,
+ OMX_BUFFERHEADERTYPE *inHeader) {
+ memset(pkt, 0, sizeof(AVPacket));
+ av_init_packet(pkt);
+
+ if (inHeader) {
+ pkt->data = (uint8_t *)inHeader->pBuffer + inHeader->nOffset;
+ pkt->size = inHeader->nFilledLen;
+ pkt->pts = inHeader->nTimeStamp; //ingore it, we will compute it
+ } else {
+ pkt->data = NULL;
+ pkt->size = 0;
+ pkt->pts = AV_NOPTS_VALUE;
+ }
+