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")) {
81 CHECK(!strcmp(name, "OMX.ffmpeg.ac3.decoder"));
85 LOGV("SoftFFmpegAudio component: %s", name);
88 CHECK_EQ(initDecoder(), (status_t)OK);
91 SoftFFmpegAudio::~SoftFFmpegAudio() {
93 LOGV("~SoftFFmpegAudio");
98 void SoftFFmpegAudio::initPorts() {
99 OMX_PARAM_PORTDEFINITIONTYPE def;
103 def.eDir = OMX_DirInput;
104 def.nBufferCountMin = kNumBuffers;
105 def.nBufferCountActual = def.nBufferCountMin;
106 def.nBufferSize = 8192;
107 def.bEnabled = OMX_TRUE;
108 def.bPopulated = OMX_FALSE;
109 def.eDomain = OMX_PortDomainAudio;
110 def.bBuffersContiguous = OMX_FALSE;
111 def.nBufferAlignment = 1;
115 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG);
116 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
119 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
120 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
123 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
124 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
127 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_AAC);
128 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
131 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_AC3);
133 //def.format.audio.eEncoding = OMX_AUDIO_CodingAC3;
134 def.format.audio.eEncoding = OMX_AUDIO_CodingAutoDetect; // right?? orz
137 CHECK(!"Should not be here. Unsupported mime type and compression format");
141 def.format.audio.pNativeRender = NULL;
142 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
147 def.eDir = OMX_DirOutput;
148 def.nBufferCountMin = kNumBuffers;
149 def.nBufferCountActual = def.nBufferCountMin;
150 def.nBufferSize = kOutputBufferSize;
151 def.bEnabled = OMX_TRUE;
152 def.bPopulated = OMX_FALSE;
153 def.eDomain = OMX_PortDomainAudio;
154 def.bBuffersContiguous = OMX_FALSE;
155 def.nBufferAlignment = 2;
157 def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
158 def.format.audio.pNativeRender = NULL;
159 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
160 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
165 static int lockmgr(void **mtx, enum AVLockOp op) {
168 *mtx = (void *)SDL_CreateMutex();
173 return !!SDL_LockMutex((SDL_mutex *)*mtx);
174 case AV_LOCK_RELEASE:
175 return !!SDL_UnlockMutex((SDL_mutex *)*mtx);
176 case AV_LOCK_DESTROY:
177 SDL_DestroyMutex((SDL_mutex *)*mtx);
183 void SoftFFmpegAudio::setAVCtxToDefault(AVCodecContext *avctx, const AVCodec *codec) {
186 avctx->workaround_bugs = 1;
188 if(avctx->lowres > codec->max_lowres){
189 LOGW("The maximum value for lowres supported by the decoder is %d",
191 avctx->lowres= codec->max_lowres;
193 avctx->idct_algo = 0;
194 avctx->skip_frame = AVDISCARD_DEFAULT;
195 avctx->skip_idct = AVDISCARD_DEFAULT;
196 avctx->skip_loop_filter = AVDISCARD_DEFAULT;
197 avctx->error_concealment = 3;
199 if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
200 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
201 if(codec->capabilities & CODEC_CAP_DR1)
202 avctx->flags |= CODEC_FLAG_EMU_EDGE;
205 status_t SoftFFmpegAudio::initDecoder() {
208 status = initFFmpeg();
212 mCtx = avcodec_alloc_context3(NULL);
215 LOGE("avcodec_alloc_context failed.");
219 mCtx->codec_type = AVMEDIA_TYPE_AUDIO;
222 mCtx->codec_id = CODEC_ID_MP3;
225 mCtx->codec_id = CODEC_ID_MP1;
228 mCtx->codec_id = CODEC_ID_MP2;
231 mCtx->codec_id = CODEC_ID_AAC;
234 mCtx->codec_id = CODEC_ID_AC3;
237 CHECK(!"Should not be here. Unsupported codec");
241 mCtx->codec = avcodec_find_decoder(mCtx->codec_id);
244 LOGE("find codec failed");
248 setAVCtxToDefault(mCtx, mCtx->codec);
250 mCtx->sample_fmt = AV_SAMPLE_FMT_S16;
252 mAudioSrcFmt = mAudioTgtFmt = AV_SAMPLE_FMT_S16;
253 mAudioSrcFreq = mAudioTgtFreq = mSamplingRate;
254 mAudioSrcChannels = mAudioTgtChannels = mNumChannels;
255 mAudioSrcChannelLayout = mAudioTgtChannelLayout =
256 av_get_default_channel_layout(mNumChannels);
258 memset(mSilenceBuffer, 0, kOutputBufferSize);
263 void SoftFFmpegAudio::deInitDecoder() {
265 //avcodec_flush_buffers(mCtx); // is it necessary? crash sometimes if call it
266 if (!mCtx->extradata) {
267 av_free(mCtx->extradata);
268 mCtx->extradata = NULL;
269 mCtx->extradata_size = 0;
283 OMX_ERRORTYPE SoftFFmpegAudio::internalGetParameter(
284 OMX_INDEXTYPE index, OMX_PTR params) {
285 int32_t channels = 0;
286 int32_t sampling_rate = 0;
289 case OMX_IndexParamAudioAac:
291 OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
292 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
294 if (aacParams->nPortIndex != 0) {
295 return OMX_ErrorUndefined;
298 aacParams->nBitRate = 0;
299 aacParams->nAudioBandWidth = 0;
300 aacParams->nAACtools = 0;
301 aacParams->nAACERtools = 0;
302 aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
303 aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
304 aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
306 aacParams->nChannels = mNumChannels;
307 aacParams->nSampleRate = mSamplingRate;
309 return OMX_ErrorNone;
311 case OMX_IndexParamAudioPcm:
313 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
314 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
316 if (pcmParams->nPortIndex > 1) {
317 return OMX_ErrorUndefined;
320 pcmParams->eNumData = OMX_NumericalDataSigned;
321 pcmParams->eEndian = OMX_EndianBig;
322 pcmParams->bInterleaved = OMX_TRUE;
323 pcmParams->nBitPerSample = 16;
324 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
325 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
326 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
328 channels = mNumChannels >= 2 ? 2 : 1;
329 sampling_rate = mSamplingRate;
330 // 4000 <= nSamplingRate <= 48000
331 if (mSamplingRate < 4000) {
332 sampling_rate = 4000;
333 } else if (mSamplingRate > 48000) {
334 sampling_rate = 48000;
337 // update src and target(except aac), only once!
338 mAudioSrcChannels = mAudioTgtChannels = channels;
339 mAudioSrcFreq = mAudioTgtFreq = sampling_rate;
340 mAudioSrcFmt = mAudioTgtFmt = AV_SAMPLE_FMT_S16;
341 mAudioSrcChannelLayout = mAudioTgtChannelLayout = av_get_default_channel_layout(channels);
343 pcmParams->nChannels = channels;
344 pcmParams->nSamplingRate = sampling_rate;
346 return OMX_ErrorNone;
350 return SimpleSoftOMXComponent::internalGetParameter(index, params);
354 OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
355 OMX_INDEXTYPE index, const OMX_PTR params) {
356 int32_t channels = 0;
357 int32_t sampling_rate = 0;
360 case OMX_IndexParamStandardComponentRole:
362 const OMX_PARAM_COMPONENTROLETYPE *roleParams =
363 (const OMX_PARAM_COMPONENTROLETYPE *)params;
365 bool supported = true;
368 if (strncmp((const char *)roleParams->cRole,
369 "audio_decoder.mp3", OMX_MAX_STRINGNAME_SIZE - 1))
373 if (strncmp((const char *)roleParams->cRole,
374 "audio_decoder.mp1", OMX_MAX_STRINGNAME_SIZE - 1))
378 if (strncmp((const char *)roleParams->cRole,
379 "audio_decoder.mp2", OMX_MAX_STRINGNAME_SIZE - 1))
383 if (strncmp((const char *)roleParams->cRole,
384 "audio_decoder.aac", OMX_MAX_STRINGNAME_SIZE - 1))
388 if (strncmp((const char *)roleParams->cRole,
389 "audio_decoder.ac3", OMX_MAX_STRINGNAME_SIZE - 1))
393 CHECK(!"Should not be here. Unsupported role.");
397 LOGE("unsupported role: %s", (const char *)roleParams->cRole);
398 return OMX_ErrorUndefined;
401 return OMX_ErrorNone;
403 case OMX_IndexParamAudioAac:
405 const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
406 (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
408 if (aacParams->nPortIndex != 0) {
409 return OMX_ErrorUndefined;
412 mNumChannels = aacParams->nChannels;
413 mSamplingRate = aacParams->nSampleRate;
415 channels = mNumChannels >= 2 ? 2 : 1;
416 sampling_rate = mSamplingRate;
417 // 4000 <= nSamplingRate <= 48000
418 if (mSamplingRate < 4000) {
419 sampling_rate = 4000;
420 } else if (mSamplingRate > 48000) {
421 sampling_rate = 48000;
424 // update src and target(only aac), only once!
425 mAudioSrcChannels = mAudioTgtChannels = channels;
426 mAudioSrcFreq = mAudioTgtFreq = sampling_rate;
427 mAudioSrcFmt = mAudioTgtFmt = AV_SAMPLE_FMT_S16;
428 mAudioSrcChannelLayout = mAudioTgtChannelLayout = av_get_default_channel_layout(channels);
430 LOGV("got OMX_IndexParamAudioAac, mNumChannels: %d, mSamplingRate: %d",
431 mNumChannels, mSamplingRate);
433 return OMX_ErrorNone;
436 LOGI("internalSetParameter, index: 0x%x", index);
437 return SimpleSoftOMXComponent::internalSetParameter(index, params);
441 void SoftFFmpegAudio::onQueueFilled(OMX_U32 portIndex) {
445 int64_t decChannelLayout;
446 int32_t inputBufferUsedLength = 0;
447 BufferInfo *inInfo = NULL;
448 OMX_BUFFERHEADERTYPE *inHeader = NULL;
450 if (mSignalledError || mOutputPortSettingsChange != NONE) {
454 List<BufferInfo *> &inQueue = getPortQueue(0);
455 List<BufferInfo *> &outQueue = getPortQueue(1);
457 while ((!inQueue.empty() || mInputBufferSize > 0 ||
458 mAudioBufferSize > 0 || mFlushComplete) && !outQueue.empty()) {
459 if (!inQueue.empty() || mInputBufferSize > 0) {
460 inInfo = *inQueue.begin();
461 inHeader = inInfo->mHeader;
467 BufferInfo *outInfo = *outQueue.begin();
468 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
470 if (inHeader && inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
471 inQueue.erase(inQueue.begin());
472 inInfo->mOwnedByUs = false;
473 notifyEmptyBufferDone(inHeader);
477 if (mReceivedEOS && (mFlushComplete || !(mCtx->codec->capabilities & CODEC_CAP_DELAY))) {
478 outHeader->nFilledLen = 0;
479 outHeader->nFlags = OMX_BUFFERFLAG_EOS;
481 outQueue.erase(outQueue.begin());
482 outInfo->mOwnedByUs = false;
483 notifyFillBufferDone(outHeader);
487 if (inHeader && inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
488 LOGI("got extradata, ignore: %d, size: %lu", mIgnoreExtradata, inHeader->nFilledLen);
489 hexdump(inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
490 if (!mExtradataReady && !mIgnoreExtradata) {
491 int orig_extradata_size = mCtx->extradata_size;
492 mCtx->extradata_size += inHeader->nFilledLen;
493 mCtx->extradata = (uint8_t *)realloc(mCtx->extradata,
494 mCtx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
495 if (!mCtx->extradata) {
496 LOGE("ffmpeg audio decoder failed to alloc extradata memory.");
497 notify(OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
498 mSignalledError = true;
502 memcpy(mCtx->extradata + orig_extradata_size,
503 inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
504 memset(mCtx->extradata + mCtx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
506 inInfo->mOwnedByUs = false;
507 inQueue.erase(inQueue.begin());
509 notifyEmptyBufferDone(inHeader);
514 if (mIgnoreExtradata) {
515 LOGI("got extradata, size: %lu, but ignore it", inHeader->nFilledLen);
516 inInfo->mOwnedByUs = false;
517 inQueue.erase(inQueue.begin());
519 notifyEmptyBufferDone(inHeader);
527 if (!mExtradataReady && !mIgnoreExtradata) {
528 LOGI("extradata is ready");
529 hexdump(mCtx->extradata, mCtx->extradata_size);
530 mExtradataReady = true;
532 LOGI("open ffmpeg decoder now");
534 err = avcodec_open2(mCtx, mCtx->codec, NULL);
536 LOGE("ffmpeg audio decoder failed to initialize. (%d)", err);
537 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
538 mSignalledError = true;
544 /* update the audio clock with the pts */
545 if (inHeader && inHeader->nOffset == 0) {
546 mAnchorTimeUs = inHeader->nTimeStamp;
547 mNumFramesOutput = 0;
548 mInputBufferSize = inHeader->nFilledLen;
551 if (inHeader && mAudioBufferSize == 0 && !mFlushComplete) {
553 av_init_packet(&pkt);
554 if (!mFlushComplete) {
555 pkt.data = (uint8_t *)inHeader->pBuffer + inHeader->nOffset;
556 pkt.size = inHeader->nFilledLen;
557 pkt.pts = inHeader->nTimeStamp; // ingore it, we will compute it
561 pkt.pts = AV_NOPTS_VALUE;
564 LOGV("pkt size: %d, pts: %lld", pkt.size, pkt.pts);
567 if (!(mFrame = avcodec_alloc_frame())) {
568 LOGE("ffmpeg audio decoder failed to alloc memory.");
569 notify(OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
570 mSignalledError = true;
574 avcodec_get_frame_defaults(mFrame);
578 inputBufferUsedLength = 0;
579 len = avcodec_decode_audio4(mCtx, mFrame, &gotFrm, &pkt);
581 LOGE("ffmpeg audio decoder failed to decode frame. (0x%x)", len);
583 /* if !mAudioConfigChanged, Don't fill the out buffer */
584 if (!mAudioConfigChanged) {
585 inInfo->mOwnedByUs = false;
586 inQueue.erase(inQueue.begin());
588 notifyEmptyBufferDone(inHeader);
593 inputBufferUsedLength = inHeader->nFilledLen;
594 /* if error, we skip the frame and play silence instead */
595 mPAudioBuffer = mSilenceBuffer;
596 mAudioBufferSize = kOutputBufferSize;
597 } else if (!gotFrm) {
598 LOGI("ffmpeg audio decoder failed to get frame.");
599 /* stop sending empty packets if the decoder is finished */
600 if (!pkt.data && mCtx->codec->capabilities & CODEC_CAP_DELAY)
601 mFlushComplete = true;
605 * FIXME, check mAudioConfigChanged when the first time you call the audio4!
606 * mCtx->sample_rate and mCtx->channels may be changed by audio decoder later, why???
608 if (!mAudioConfigChanged) {
609 if (mCtx->channels != mNumChannels || mCtx->sample_rate != mSamplingRate || mCtx->sample_fmt != mSamplingFmt) {
610 LOGI("audio OMX_EventPortSettingsChanged, mCtx->channels: %d, mNumChannels: %d, mCtx->sample_rate: %d, mSamplingRate: %d",
611 mCtx->channels, mNumChannels, mCtx->sample_rate, mSamplingRate);
612 mNumChannels = mCtx->channels;
613 mSamplingRate = mCtx->sample_rate;
614 mSamplingFmt = mCtx->sample_fmt;
615 mAudioConfigChanged = true;
616 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
617 mOutputPortSettingsChange = AWAITING_DISABLED;
620 // match with the default, set mAudioConfigChanged true anyway!
621 mAudioConfigChanged = true;
625 dataSize = av_samples_get_buffer_size(NULL, mNumChannels, mFrame->nb_samples, mSamplingFmt, 1);
627 decChannelLayout = av_get_default_channel_layout(mNumChannels);
628 if (mSamplingFmt != mAudioSrcFmt ||
629 decChannelLayout != mAudioSrcChannelLayout ||
630 mSamplingRate != mAudioSrcFreq ) {
633 mSwrCtx = swr_alloc_set_opts(NULL,
634 mAudioTgtChannelLayout, mAudioTgtFmt, mAudioTgtFreq,
635 decChannelLayout, mSamplingFmt, mSamplingRate,
637 if (!mSwrCtx || swr_init(mSwrCtx) < 0) {
638 LOGE("Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!",
640 av_get_sample_fmt_name(mSamplingFmt),
643 av_get_sample_fmt_name(mAudioTgtFmt),
645 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
646 mSignalledError = true;
650 LOGI("Create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!",
652 av_get_sample_fmt_name(mSamplingFmt),
655 av_get_sample_fmt_name(mAudioTgtFmt),
658 mAudioSrcChannelLayout = decChannelLayout;
659 mAudioSrcChannels = mNumChannels;
660 mAudioSrcFreq = mSamplingRate;
661 mAudioSrcFmt = mSamplingFmt;
665 const uint8_t *in[] = { mFrame->data[0] };
666 uint8_t *out[] = {mAudioBuf2};
667 int len2 = swr_convert(mSwrCtx, out, sizeof(mAudioBuf2) / mAudioTgtChannels / av_get_bytes_per_sample(mAudioTgtFmt),
668 in, mFrame->nb_samples);
670 LOGE("audio_resample() failed");
673 if (len2 == sizeof(mAudioBuf2) / mAudioTgtChannels / av_get_bytes_per_sample(mAudioTgtFmt)) {
674 LOGE("warning: audio buffer is probably too small");
677 mPAudioBuffer = mAudioBuf2;
678 mAudioBufferSize = len2 * mAudioTgtChannels * av_get_bytes_per_sample(mAudioTgtFmt);
680 mPAudioBuffer = mFrame->data[0];
681 mAudioBufferSize = dataSize;
684 inputBufferUsedLength = len;
686 LOGV("ffmpeg audio decoder get frame. (%d), mAudioBufferSize: %d", len, mAudioBufferSize);
691 size_t copyToOutputBufferLen = mAudioBufferSize;
692 if (mAudioBufferSize > kOutputBufferSize)
693 copyToOutputBufferLen = kOutputBufferSize;
695 outHeader->nOffset = 0;
696 outHeader->nFilledLen = copyToOutputBufferLen;
697 outHeader->nTimeStamp = mAnchorTimeUs
698 + (mNumFramesOutput * 1000000ll) / mSamplingRate;
699 memcpy(outHeader->pBuffer, mPAudioBuffer, copyToOutputBufferLen);
700 outHeader->nFlags = 0;
702 mPAudioBuffer += copyToOutputBufferLen;
703 mAudioBufferSize -= copyToOutputBufferLen;
704 mNumFramesOutput += copyToOutputBufferLen / av_get_bytes_per_sample(mCtx->sample_fmt) / mNumChannels;
707 CHECK_GE(inHeader->nFilledLen, inputBufferUsedLength);
708 inHeader->nOffset += inputBufferUsedLength;
709 inHeader->nFilledLen -= inputBufferUsedLength;
710 mInputBufferSize -= inputBufferUsedLength;
711 if (inHeader->nFilledLen == 0) {
712 inInfo->mOwnedByUs = false;
713 inQueue.erase(inQueue.begin());
715 notifyEmptyBufferDone(inHeader);
718 mInputBufferSize = 0;
722 outInfo->mOwnedByUs = false;
723 outQueue.erase(outQueue.begin());
725 notifyFillBufferDone(outHeader);
730 void SoftFFmpegAudio::onPortFlushCompleted(OMX_U32 portIndex) {
731 if (portIndex == 0 && mCtx) {
732 // Make sure that the next buffer output does not still
733 // depend on fragments from the last one decoded.
734 avcodec_flush_buffers(mCtx);
739 void SoftFFmpegAudio::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
740 if (portIndex != 1) {
744 switch (mOutputPortSettingsChange) {
748 case AWAITING_DISABLED:
751 mOutputPortSettingsChange = AWAITING_ENABLED;
757 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
759 mOutputPortSettingsChange = NONE;
765 } // namespace android
767 android::SoftOMXComponent *createSoftOMXComponent(
768 const char *name, const OMX_CALLBACKTYPE *callbacks,
769 OMX_PTR appData, OMX_COMPONENTTYPE **component) {
770 return new android::SoftFFmpegAudio(name, callbacks, appData, component);