2 * Copyright 2012 Michael Chen <omxcodec@gmail.com>
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #define LOG_TAG "SoftFFmpegAudio"
19 #include <utils/Log.h>
21 #include "SoftFFmpegAudio.h"
23 #include <media/stagefright/foundation/ADebug.h>
24 #include <media/stagefright/foundation/hexdump.h>
25 #include <media/stagefright/MediaDefs.h>
27 #include "ffmpeg_utils/ffmpeg_utils.h"
38 static void InitOMXParams(T *params) {
39 params->nSize = sizeof(T);
40 params->nVersion.s.nVersionMajor = 1;
41 params->nVersion.s.nVersionMinor = 0;
42 params->nVersion.s.nRevision = 0;
43 params->nVersion.s.nStep = 0;
46 SoftFFmpegAudio::SoftFFmpegAudio(
48 const OMX_CALLBACKTYPE *callbacks,
50 OMX_COMPONENTTYPE **component)
51 : SimpleSoftOMXComponent(name, callbacks, appData, component),
56 mExtradataReady(false),
57 mIgnoreExtradata(false),
58 mFlushComplete(false),
59 mSignalledError(false),
68 mSamplingFmt(AV_SAMPLE_FMT_S16),
69 mAudioConfigChanged(false),
70 mOutputPortSettingsChange(NONE) {
71 if (!strcmp(name, "OMX.ffmpeg.mp3.decoder")) {
73 mIgnoreExtradata = true;
74 } else if (!strcmp(name, "OMX.ffmpeg.mp1.decoder")) {
76 } else if (!strcmp(name, "OMX.ffmpeg.mp2.decoder")) {
78 } else if (!strcmp(name, "OMX.ffmpeg.aac.decoder")) {
80 } else if (!strcmp(name, "OMX.ffmpeg.ape.decoder")) {
82 } else if (!strcmp(name, "OMX.ffmpeg.wma.decoder")) {
84 } else if (!strcmp(name, "OMX.ffmpeg.dts.decoder")) {
86 } else if (!strcmp(name, "OMX.ffmpeg.ra.decoder")) {
89 CHECK(!strcmp(name, "OMX.ffmpeg.ac3.decoder"));
93 LOGV("SoftFFmpegAudio component: %s", name);
96 CHECK_EQ(initDecoder(), (status_t)OK);
99 SoftFFmpegAudio::~SoftFFmpegAudio() {
101 LOGV("~SoftFFmpegAudio");
106 void SoftFFmpegAudio::initPorts() {
107 OMX_PARAM_PORTDEFINITIONTYPE def;
111 def.eDir = OMX_DirInput;
112 def.nBufferCountMin = kNumBuffers;
113 def.nBufferCountActual = def.nBufferCountMin;
114 def.nBufferSize = 8192;
115 def.bEnabled = OMX_TRUE;
116 def.bPopulated = OMX_FALSE;
117 def.eDomain = OMX_PortDomainAudio;
118 def.bBuffersContiguous = OMX_FALSE;
119 def.nBufferAlignment = 1;
123 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG);
124 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
127 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
128 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
131 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
132 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
135 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_AAC);
136 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
139 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_AC3);
141 //def.format.audio.eEncoding = OMX_AUDIO_CodingAC3;
142 def.format.audio.eEncoding = OMX_AUDIO_CodingAutoDetect; // right?? orz
145 CHECK(!"Should not be here. Unsupported mime type and compression format");
149 def.format.audio.pNativeRender = NULL;
150 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
155 def.eDir = OMX_DirOutput;
156 def.nBufferCountMin = kNumBuffers;
157 def.nBufferCountActual = def.nBufferCountMin;
158 def.nBufferSize = kOutputBufferSize;
159 def.bEnabled = OMX_TRUE;
160 def.bPopulated = OMX_FALSE;
161 def.eDomain = OMX_PortDomainAudio;
162 def.bBuffersContiguous = OMX_FALSE;
163 def.nBufferAlignment = 2;
165 def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
166 def.format.audio.pNativeRender = NULL;
167 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
168 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
173 void SoftFFmpegAudio::setAVCtxToDefault(AVCodecContext *avctx, const AVCodec *codec) {
176 avctx->workaround_bugs = 1;
178 if(avctx->lowres > codec->max_lowres){
179 LOGW("The maximum value for lowres supported by the decoder is %d",
181 avctx->lowres= codec->max_lowres;
183 avctx->idct_algo = 0;
184 avctx->skip_frame = AVDISCARD_DEFAULT;
185 avctx->skip_idct = AVDISCARD_DEFAULT;
186 avctx->skip_loop_filter = AVDISCARD_DEFAULT;
187 avctx->error_concealment = 3;
189 if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
190 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
191 if(codec->capabilities & CODEC_CAP_DR1)
192 avctx->flags |= CODEC_FLAG_EMU_EDGE;
195 status_t SoftFFmpegAudio::initDecoder() {
198 status = initFFmpeg();
202 mCtx = avcodec_alloc_context3(NULL);
205 LOGE("avcodec_alloc_context failed.");
209 mCtx->codec_type = AVMEDIA_TYPE_AUDIO;
212 mCtx->codec_id = CODEC_ID_MP3;
215 mCtx->codec_id = CODEC_ID_MP1;
218 mCtx->codec_id = CODEC_ID_MP2;
221 mCtx->codec_id = CODEC_ID_AAC;
224 mCtx->codec_id = CODEC_ID_AC3;
227 CHECK(!"Should not be here. Unsupported codec");
231 mCtx->codec = avcodec_find_decoder(mCtx->codec_id);
234 LOGE("find codec failed");
238 setAVCtxToDefault(mCtx, mCtx->codec);
240 mCtx->sample_fmt = AV_SAMPLE_FMT_S16;
242 mAudioSrcFmt = mAudioTgtFmt = AV_SAMPLE_FMT_S16;
243 mAudioSrcFreq = mAudioTgtFreq = mSamplingRate;
244 mAudioSrcChannels = mAudioTgtChannels = mNumChannels;
245 mAudioSrcChannelLayout = mAudioTgtChannelLayout =
246 av_get_default_channel_layout(mNumChannels);
248 memset(mSilenceBuffer, 0, kOutputBufferSize);
253 void SoftFFmpegAudio::deInitDecoder() {
255 //avcodec_flush_buffers(mCtx); // is it necessary? crash sometimes if call it
256 if (!mCtx->extradata) {
257 av_free(mCtx->extradata);
258 mCtx->extradata = NULL;
259 mCtx->extradata_size = 0;
273 OMX_ERRORTYPE SoftFFmpegAudio::internalGetParameter(
274 OMX_INDEXTYPE index, OMX_PTR params) {
275 int32_t channels = 0;
276 int32_t sampling_rate = 0;
279 case OMX_IndexParamAudioAac:
281 OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
282 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
284 if (aacParams->nPortIndex != 0) {
285 return OMX_ErrorUndefined;
288 aacParams->nBitRate = 0;
289 aacParams->nAudioBandWidth = 0;
290 aacParams->nAACtools = 0;
291 aacParams->nAACERtools = 0;
292 aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
293 aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
294 aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
296 aacParams->nChannels = mNumChannels;
297 aacParams->nSampleRate = mSamplingRate;
299 return OMX_ErrorNone;
301 case OMX_IndexParamAudioPcm:
303 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
304 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
306 if (pcmParams->nPortIndex > 1) {
307 return OMX_ErrorUndefined;
310 pcmParams->eNumData = OMX_NumericalDataSigned;
311 pcmParams->eEndian = OMX_EndianBig;
312 pcmParams->bInterleaved = OMX_TRUE;
313 pcmParams->nBitPerSample = 16;
314 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
315 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
316 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
318 channels = mNumChannels >= 2 ? 2 : 1;
319 sampling_rate = mSamplingRate;
320 // 4000 <= nSamplingRate <= 48000
321 if (mSamplingRate < 4000) {
322 sampling_rate = 4000;
323 } else if (mSamplingRate > 48000) {
324 sampling_rate = 48000;
327 // update src and target(except aac), only once!
328 mAudioSrcChannels = mAudioTgtChannels = channels;
329 mAudioSrcFreq = mAudioTgtFreq = sampling_rate;
330 mAudioSrcFmt = mAudioTgtFmt = AV_SAMPLE_FMT_S16;
331 mAudioSrcChannelLayout = mAudioTgtChannelLayout = av_get_default_channel_layout(channels);
333 pcmParams->nChannels = channels;
334 pcmParams->nSamplingRate = sampling_rate;
336 return OMX_ErrorNone;
340 return SimpleSoftOMXComponent::internalGetParameter(index, params);
344 OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
345 OMX_INDEXTYPE index, const OMX_PTR params) {
346 int32_t channels = 0;
347 int32_t sampling_rate = 0;
350 case OMX_IndexParamStandardComponentRole:
352 const OMX_PARAM_COMPONENTROLETYPE *roleParams =
353 (const OMX_PARAM_COMPONENTROLETYPE *)params;
355 bool supported = true;
358 if (strncmp((const char *)roleParams->cRole,
359 "audio_decoder.mp3", OMX_MAX_STRINGNAME_SIZE - 1))
363 if (strncmp((const char *)roleParams->cRole,
364 "audio_decoder.mp1", OMX_MAX_STRINGNAME_SIZE - 1))
368 if (strncmp((const char *)roleParams->cRole,
369 "audio_decoder.mp2", OMX_MAX_STRINGNAME_SIZE - 1))
373 if (strncmp((const char *)roleParams->cRole,
374 "audio_decoder.aac", OMX_MAX_STRINGNAME_SIZE - 1))
378 if (strncmp((const char *)roleParams->cRole,
379 "audio_decoder.ac3", OMX_MAX_STRINGNAME_SIZE - 1))
383 CHECK(!"Should not be here. Unsupported role.");
387 LOGE("unsupported role: %s", (const char *)roleParams->cRole);
388 return OMX_ErrorUndefined;
391 return OMX_ErrorNone;
393 case OMX_IndexParamAudioAac:
395 const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
396 (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
398 if (aacParams->nPortIndex != 0) {
399 return OMX_ErrorUndefined;
402 mNumChannels = aacParams->nChannels;
403 mSamplingRate = aacParams->nSampleRate;
405 channels = mNumChannels >= 2 ? 2 : 1;
406 sampling_rate = mSamplingRate;
407 // 4000 <= nSamplingRate <= 48000
408 if (mSamplingRate < 4000) {
409 sampling_rate = 4000;
410 } else if (mSamplingRate > 48000) {
411 sampling_rate = 48000;
414 // update src and target(only aac), only once!
415 mAudioSrcChannels = mAudioTgtChannels = channels;
416 mAudioSrcFreq = mAudioTgtFreq = sampling_rate;
417 mAudioSrcFmt = mAudioTgtFmt = AV_SAMPLE_FMT_S16;
418 mAudioSrcChannelLayout = mAudioTgtChannelLayout = av_get_default_channel_layout(channels);
420 LOGV("got OMX_IndexParamAudioAac, mNumChannels: %d, mSamplingRate: %d",
421 mNumChannels, mSamplingRate);
423 return OMX_ErrorNone;
426 LOGI("internalSetParameter, index: 0x%x", index);
427 return SimpleSoftOMXComponent::internalSetParameter(index, params);
431 void SoftFFmpegAudio::onQueueFilled(OMX_U32 portIndex) {
435 int64_t decChannelLayout;
436 int32_t inputBufferUsedLength = 0;
437 BufferInfo *inInfo = NULL;
438 OMX_BUFFERHEADERTYPE *inHeader = NULL;
440 if (mSignalledError || mOutputPortSettingsChange != NONE) {
444 List<BufferInfo *> &inQueue = getPortQueue(0);
445 List<BufferInfo *> &outQueue = getPortQueue(1);
447 while ((!inQueue.empty() || mInputBufferSize > 0 ||
448 mAudioBufferSize > 0 || mFlushComplete) && !outQueue.empty()) {
449 if (!inQueue.empty() || mInputBufferSize > 0) {
450 inInfo = *inQueue.begin();
451 inHeader = inInfo->mHeader;
457 BufferInfo *outInfo = *outQueue.begin();
458 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
460 if (inHeader && inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
461 inQueue.erase(inQueue.begin());
462 inInfo->mOwnedByUs = false;
463 notifyEmptyBufferDone(inHeader);
467 if (mReceivedEOS && (mFlushComplete || !(mCtx->codec->capabilities & CODEC_CAP_DELAY))) {
468 outHeader->nFilledLen = 0;
469 outHeader->nFlags = OMX_BUFFERFLAG_EOS;
471 outQueue.erase(outQueue.begin());
472 outInfo->mOwnedByUs = false;
473 notifyFillBufferDone(outHeader);
477 if (inHeader && inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
478 LOGI("got extradata, ignore: %d, size: %lu", mIgnoreExtradata, inHeader->nFilledLen);
479 hexdump(inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
480 if (!mExtradataReady && !mIgnoreExtradata) {
481 int orig_extradata_size = mCtx->extradata_size;
482 mCtx->extradata_size += inHeader->nFilledLen;
483 mCtx->extradata = (uint8_t *)realloc(mCtx->extradata,
484 mCtx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
485 if (!mCtx->extradata) {
486 LOGE("ffmpeg audio decoder failed to alloc extradata memory.");
487 notify(OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
488 mSignalledError = true;
492 memcpy(mCtx->extradata + orig_extradata_size,
493 inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
494 memset(mCtx->extradata + mCtx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
496 inInfo->mOwnedByUs = false;
497 inQueue.erase(inQueue.begin());
499 notifyEmptyBufferDone(inHeader);
504 if (mIgnoreExtradata) {
505 LOGI("got extradata, size: %lu, but ignore it", inHeader->nFilledLen);
506 inInfo->mOwnedByUs = false;
507 inQueue.erase(inQueue.begin());
509 notifyEmptyBufferDone(inHeader);
517 if (!mExtradataReady && !mIgnoreExtradata) {
518 LOGI("extradata is ready");
519 hexdump(mCtx->extradata, mCtx->extradata_size);
520 mExtradataReady = true;
522 LOGI("open ffmpeg decoder now");
524 err = avcodec_open2(mCtx, mCtx->codec, NULL);
526 LOGE("ffmpeg audio decoder failed to initialize. (%d)", err);
527 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
528 mSignalledError = true;
534 /* update the audio clock with the pts */
535 if (inHeader && inHeader->nOffset == 0) {
536 mAnchorTimeUs = inHeader->nTimeStamp;
537 mNumFramesOutput = 0;
538 mInputBufferSize = inHeader->nFilledLen;
541 if (inHeader && mAudioBufferSize == 0 && !mFlushComplete) {
543 av_init_packet(&pkt);
544 if (!mFlushComplete) {
545 pkt.data = (uint8_t *)inHeader->pBuffer + inHeader->nOffset;
546 pkt.size = inHeader->nFilledLen;
547 pkt.pts = inHeader->nTimeStamp; // ingore it, we will compute it
551 pkt.pts = AV_NOPTS_VALUE;
554 LOGV("pkt size: %d, pts: %lld", pkt.size, pkt.pts);
557 if (!(mFrame = avcodec_alloc_frame())) {
558 LOGE("ffmpeg audio decoder failed to alloc memory.");
559 notify(OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
560 mSignalledError = true;
564 avcodec_get_frame_defaults(mFrame);
568 inputBufferUsedLength = 0;
569 len = avcodec_decode_audio4(mCtx, mFrame, &gotFrm, &pkt);
571 LOGE("ffmpeg audio decoder failed to decode frame. (0x%x)", len);
573 /* if !mAudioConfigChanged, Don't fill the out buffer */
574 if (!mAudioConfigChanged) {
575 inInfo->mOwnedByUs = false;
576 inQueue.erase(inQueue.begin());
578 notifyEmptyBufferDone(inHeader);
583 inputBufferUsedLength = inHeader->nFilledLen;
584 /* if error, we skip the frame and play silence instead */
585 mPAudioBuffer = mSilenceBuffer;
586 mAudioBufferSize = kOutputBufferSize;
587 } else if (!gotFrm) {
588 LOGI("ffmpeg audio decoder failed to get frame.");
589 /* stop sending empty packets if the decoder is finished */
590 if (!pkt.data && mCtx->codec->capabilities & CODEC_CAP_DELAY)
591 mFlushComplete = true;
595 * FIXME, check mAudioConfigChanged when the first time you call the audio4!
596 * mCtx->sample_rate and mCtx->channels may be changed by audio decoder later, why???
598 if (!mAudioConfigChanged) {
599 if (mCtx->channels != mNumChannels || mCtx->sample_rate != mSamplingRate || mCtx->sample_fmt != mSamplingFmt) {
600 LOGI("audio OMX_EventPortSettingsChanged, mCtx->channels: %d, mNumChannels: %d, mCtx->sample_rate: %d, mSamplingRate: %d",
601 mCtx->channels, mNumChannels, mCtx->sample_rate, mSamplingRate);
602 mNumChannels = mCtx->channels;
603 mSamplingRate = mCtx->sample_rate;
604 mSamplingFmt = mCtx->sample_fmt;
605 mAudioConfigChanged = true;
606 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
607 mOutputPortSettingsChange = AWAITING_DISABLED;
610 // match with the default, set mAudioConfigChanged true anyway!
611 mAudioConfigChanged = true;
615 dataSize = av_samples_get_buffer_size(NULL, mNumChannels, mFrame->nb_samples, mSamplingFmt, 1);
617 decChannelLayout = av_get_default_channel_layout(mNumChannels);
618 if (mSamplingFmt != mAudioSrcFmt ||
619 decChannelLayout != mAudioSrcChannelLayout ||
620 mSamplingRate != mAudioSrcFreq ) {
623 mSwrCtx = swr_alloc_set_opts(NULL,
624 mAudioTgtChannelLayout, mAudioTgtFmt, mAudioTgtFreq,
625 decChannelLayout, mSamplingFmt, mSamplingRate,
627 if (!mSwrCtx || swr_init(mSwrCtx) < 0) {
628 LOGE("Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!",
630 av_get_sample_fmt_name(mSamplingFmt),
633 av_get_sample_fmt_name(mAudioTgtFmt),
635 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
636 mSignalledError = true;
640 LOGI("Create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!",
642 av_get_sample_fmt_name(mSamplingFmt),
645 av_get_sample_fmt_name(mAudioTgtFmt),
648 mAudioSrcChannelLayout = decChannelLayout;
649 mAudioSrcChannels = mNumChannels;
650 mAudioSrcFreq = mSamplingRate;
651 mAudioSrcFmt = mSamplingFmt;
655 const uint8_t *in[] = { mFrame->data[0] };
656 uint8_t *out[] = {mAudioBuf2};
657 int len2 = swr_convert(mSwrCtx, out, sizeof(mAudioBuf2) / mAudioTgtChannels / av_get_bytes_per_sample(mAudioTgtFmt),
658 in, mFrame->nb_samples);
660 LOGE("audio_resample() failed");
663 if (len2 == sizeof(mAudioBuf2) / mAudioTgtChannels / av_get_bytes_per_sample(mAudioTgtFmt)) {
664 LOGE("warning: audio buffer is probably too small");
667 mPAudioBuffer = mAudioBuf2;
668 mAudioBufferSize = len2 * mAudioTgtChannels * av_get_bytes_per_sample(mAudioTgtFmt);
670 mPAudioBuffer = mFrame->data[0];
671 mAudioBufferSize = dataSize;
674 inputBufferUsedLength = len;
676 LOGV("ffmpeg audio decoder get frame. (%d), mAudioBufferSize: %d", len, mAudioBufferSize);
681 size_t copyToOutputBufferLen = mAudioBufferSize;
682 if (mAudioBufferSize > kOutputBufferSize)
683 copyToOutputBufferLen = kOutputBufferSize;
685 outHeader->nOffset = 0;
686 outHeader->nFilledLen = copyToOutputBufferLen;
687 outHeader->nTimeStamp = mAnchorTimeUs
688 + (mNumFramesOutput * 1000000ll) / mSamplingRate;
689 memcpy(outHeader->pBuffer, mPAudioBuffer, copyToOutputBufferLen);
690 outHeader->nFlags = 0;
692 mPAudioBuffer += copyToOutputBufferLen;
693 mAudioBufferSize -= copyToOutputBufferLen;
694 mNumFramesOutput += copyToOutputBufferLen / av_get_bytes_per_sample(mCtx->sample_fmt) / mNumChannels;
697 CHECK_GE(inHeader->nFilledLen, inputBufferUsedLength);
698 inHeader->nOffset += inputBufferUsedLength;
699 inHeader->nFilledLen -= inputBufferUsedLength;
700 mInputBufferSize -= inputBufferUsedLength;
701 if (inHeader->nFilledLen == 0) {
702 inInfo->mOwnedByUs = false;
703 inQueue.erase(inQueue.begin());
705 notifyEmptyBufferDone(inHeader);
708 mInputBufferSize = 0;
712 outInfo->mOwnedByUs = false;
713 outQueue.erase(outQueue.begin());
715 notifyFillBufferDone(outHeader);
720 void SoftFFmpegAudio::onPortFlushCompleted(OMX_U32 portIndex) {
721 if (portIndex == 0 && mCtx) {
722 // Make sure that the next buffer output does not still
723 // depend on fragments from the last one decoded.
724 avcodec_flush_buffers(mCtx);
729 void SoftFFmpegAudio::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
730 if (portIndex != 1) {
734 switch (mOutputPortSettingsChange) {
738 case AWAITING_DISABLED:
741 mOutputPortSettingsChange = AWAITING_ENABLED;
747 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
749 mOutputPortSettingsChange = NONE;
755 } // namespace android
757 android::SoftOMXComponent *createSoftOMXComponent(
758 const char *name, const OMX_CALLBACKTYPE *callbacks,
759 OMX_PTR appData, OMX_COMPONENTTYPE **component) {
760 return new android::SoftFFmpegAudio(name, callbacks, appData, component);