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.
17 //#define LOG_NDEBUG 0
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 mAudioConfigChanged(false),
69 mOutputPortSettingsChange(NONE) {
70 if (!strcmp(name, "OMX.ffmpeg.mp3.decoder")) {
72 mIgnoreExtradata = true;
73 } else if (!strcmp(name, "OMX.ffmpeg.mp1.decoder")) {
75 } else if (!strcmp(name, "OMX.ffmpeg.mp2.decoder")) {
77 } else if (!strcmp(name, "OMX.ffmpeg.aac.decoder")) {
80 CHECK(!strcmp(name, "OMX.ffmpeg.ac3.decoder"));
84 LOGV("SoftFFmpegAudio component: %s", name);
87 CHECK_EQ(initDecoder(), (status_t)OK);
90 SoftFFmpegAudio::~SoftFFmpegAudio() {
92 LOGV("~SoftFFmpegAudio");
97 void SoftFFmpegAudio::initPorts() {
98 OMX_PARAM_PORTDEFINITIONTYPE def;
102 def.eDir = OMX_DirInput;
103 def.nBufferCountMin = kNumBuffers;
104 def.nBufferCountActual = def.nBufferCountMin;
105 def.nBufferSize = 8192;
106 def.bEnabled = OMX_TRUE;
107 def.bPopulated = OMX_FALSE;
108 def.eDomain = OMX_PortDomainAudio;
109 def.bBuffersContiguous = OMX_FALSE;
110 def.nBufferAlignment = 1;
114 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG);
115 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
118 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
119 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
122 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
123 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
126 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_AAC);
127 def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
130 def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_AC3);
132 //def.format.audio.eEncoding = OMX_AUDIO_CodingAC3;
133 def.format.audio.eEncoding = OMX_AUDIO_CodingAutoDetect; // right?? orz
136 CHECK(!"Should not be here. Unsupported mime type and compression format");
140 def.format.audio.pNativeRender = NULL;
141 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
146 def.eDir = OMX_DirOutput;
147 def.nBufferCountMin = kNumBuffers;
148 def.nBufferCountActual = def.nBufferCountMin;
149 def.nBufferSize = kOutputBufferSize;
150 def.bEnabled = OMX_TRUE;
151 def.bPopulated = OMX_FALSE;
152 def.eDomain = OMX_PortDomainAudio;
153 def.bBuffersContiguous = OMX_FALSE;
154 def.nBufferAlignment = 2;
156 def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
157 def.format.audio.pNativeRender = NULL;
158 def.format.audio.bFlagErrorConcealment = OMX_FALSE;
159 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
164 static int lockmgr(void **mtx, enum AVLockOp op) {
167 *mtx = (void *)SDL_CreateMutex();
172 return !!SDL_LockMutex((SDL_mutex *)*mtx);
173 case AV_LOCK_RELEASE:
174 return !!SDL_UnlockMutex((SDL_mutex *)*mtx);
175 case AV_LOCK_DESTROY:
176 SDL_DestroyMutex((SDL_mutex *)*mtx);
182 status_t SoftFFmpegAudio::initFFmpeg() {
183 //nam_av_log_set_flags(AV_LOG_SKIP_REPEATED);
184 //av_log_set_level(AV_LOG_DEBUG);
185 av_log_set_callback(nam_av_log_callback);
187 /* register all codecs, demux and protocols */
188 avcodec_register_all();
190 avdevice_register_all();
193 avformat_network_init();
197 if (av_lockmgr_register(lockmgr)) {
198 LOGE("could not initialize lock manager!");
205 void SoftFFmpegAudio::deInitFFmpeg() {
206 av_lockmgr_register(NULL);
208 avformat_network_deinit();
211 void SoftFFmpegAudio::setAVCtxToDefault(AVCodecContext *avctx, const AVCodec *codec) {
214 avctx->workaround_bugs = 1;
216 if(avctx->lowres > codec->max_lowres){
217 LOGW("The maximum value for lowres supported by the decoder is %d",
219 avctx->lowres= codec->max_lowres;
221 avctx->idct_algo = 0;
222 avctx->skip_frame = AVDISCARD_DEFAULT;
223 avctx->skip_idct = AVDISCARD_DEFAULT;
224 avctx->skip_loop_filter = AVDISCARD_DEFAULT;
225 avctx->error_concealment = 3;
227 if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
228 if (fast) avctx->flags2 |= CODEC_FLAG2_FAST;
229 if(codec->capabilities & CODEC_CAP_DR1)
230 avctx->flags |= CODEC_FLAG_EMU_EDGE;
233 status_t SoftFFmpegAudio::initDecoder() {
236 status = initFFmpeg();
240 mCtx = avcodec_alloc_context3(NULL);
243 LOGE("avcodec_alloc_context failed.");
244 return OMX_ErrorInsufficientResources;
247 mCtx->codec_type = AVMEDIA_TYPE_AUDIO;
250 mCtx->codec_id = CODEC_ID_MP3;
253 mCtx->codec_id = CODEC_ID_MP1;
256 mCtx->codec_id = CODEC_ID_MP2;
259 mCtx->codec_id = CODEC_ID_AAC;
262 mCtx->codec_id = CODEC_ID_AC3;
265 CHECK(!"Should not be here. Unsupported codec");
269 mCtx->codec = avcodec_find_decoder(mCtx->codec_id);
272 LOGE("find codec failed");
273 return OMX_ErrorNotImplemented;
276 setAVCtxToDefault(mCtx, mCtx->codec);
279 // FIXME, defer to open? ref: OMXCodec.cpp:setAudioOutputFormat
280 err = avcodec_open2(mCtx, mCtx->codec, NULL);
282 LOGE("ffmpeg audio decoder failed to initialize. (%d)", err);
283 return OMX_ErrorUndefined;
287 mCtx->sample_fmt = AV_SAMPLE_FMT_S16;
289 mAudioSrcFmt = mAudioTgtFmt = AV_SAMPLE_FMT_S16;
290 mAudioSrcFreq = mAudioTgtFreq = mSamplingRate;
291 mAudioSrcChannels = mAudioTgtChannels = mNumChannels;
292 mAudioSrcChannelLayout = mAudioTgtChannelLayout =
293 av_get_default_channel_layout(mNumChannels);
295 memset(mSilenceBuffer, 0, kOutputBufferSize);
297 return OMX_ErrorNone;
300 void SoftFFmpegAudio::deInitDecoder() {
302 avcodec_flush_buffers(mCtx);
303 if (!mCtx->extradata) {
304 av_free(mCtx->extradata);
305 mCtx->extradata = NULL;
306 mCtx->extradata_size = 0;
320 OMX_ERRORTYPE SoftFFmpegAudio::internalGetParameter(
321 OMX_INDEXTYPE index, OMX_PTR params) {
323 case OMX_IndexParamAudioAac:
325 OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
326 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
328 if (aacParams->nPortIndex != 0) {
329 return OMX_ErrorUndefined;
332 aacParams->nBitRate = 0;
333 aacParams->nAudioBandWidth = 0;
334 aacParams->nAACtools = 0;
335 aacParams->nAACERtools = 0;
336 aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
337 aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
338 aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
340 aacParams->nChannels = mNumChannels;
341 aacParams->nSampleRate = mSamplingRate;
343 return OMX_ErrorNone;
345 case OMX_IndexParamAudioPcm:
347 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
348 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
350 if (pcmParams->nPortIndex > 1) {
351 return OMX_ErrorUndefined;
354 pcmParams->eNumData = OMX_NumericalDataSigned;
355 pcmParams->eEndian = OMX_EndianBig;
356 pcmParams->bInterleaved = OMX_TRUE;
357 pcmParams->nBitPerSample = 16;
358 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
359 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
360 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
362 pcmParams->nChannels = mNumChannels;
363 pcmParams->nSamplingRate = mSamplingRate;
365 return OMX_ErrorNone;
369 return SimpleSoftOMXComponent::internalGetParameter(index, params);
373 OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
374 OMX_INDEXTYPE index, const OMX_PTR params) {
376 case OMX_IndexParamStandardComponentRole:
378 const OMX_PARAM_COMPONENTROLETYPE *roleParams =
379 (const OMX_PARAM_COMPONENTROLETYPE *)params;
381 bool supported = true;
384 if (strncmp((const char *)roleParams->cRole,
385 "audio_decoder.mp3", OMX_MAX_STRINGNAME_SIZE - 1))
389 if (strncmp((const char *)roleParams->cRole,
390 "audio_decoder.mp1", OMX_MAX_STRINGNAME_SIZE - 1))
394 if (strncmp((const char *)roleParams->cRole,
395 "audio_decoder.mp2", OMX_MAX_STRINGNAME_SIZE - 1))
399 if (strncmp((const char *)roleParams->cRole,
400 "audio_decoder.aac", OMX_MAX_STRINGNAME_SIZE - 1))
404 if (strncmp((const char *)roleParams->cRole,
405 "audio_decoder.ac3", OMX_MAX_STRINGNAME_SIZE - 1))
409 CHECK(!"Should not be here. Unsupported role.");
413 LOGE("unsupported role: %s", (const char *)roleParams->cRole);
414 return OMX_ErrorUndefined;
417 return OMX_ErrorNone;
419 case OMX_IndexParamAudioAac:
421 const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
422 (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
424 if (aacParams->nPortIndex != 0) {
425 return OMX_ErrorUndefined;
428 mNumChannels = aacParams->nChannels;
429 mSamplingRate = aacParams->nSampleRate;
431 LOGV("got OMX_IndexParamAudioAac, mNumChannels: %d, mSamplingRate: %d",
432 mNumChannels, mSamplingRate);
434 return OMX_ErrorNone;
437 LOGI("internalSetParameter, index: 0x%x", index);
438 return SimpleSoftOMXComponent::internalSetParameter(index, params);
442 void SoftFFmpegAudio::onQueueFilled(OMX_U32 portIndex) {
445 size_t resampledDataSize = 0;
446 int64_t decChannelLayout;
447 int32_t inputBufferUsedLength = 0;
448 BufferInfo *inInfo = NULL;
449 OMX_BUFFERHEADERTYPE *inHeader = NULL;
451 if (mSignalledError || mOutputPortSettingsChange != NONE) {
455 List<BufferInfo *> &inQueue = getPortQueue(0);
456 List<BufferInfo *> &outQueue = getPortQueue(1);
458 while ((!inQueue.empty() || mInputBufferSize > 0 ||
459 mAudioBufferSize > 0 || mFlushComplete) && !outQueue.empty()) {
460 if (!inQueue.empty() || mInputBufferSize > 0) {
461 inInfo = *inQueue.begin();
462 inHeader = inInfo->mHeader;
468 BufferInfo *outInfo = *outQueue.begin();
469 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
471 if (!mAudioConfigChanged && mMode == MODE_AAC &&
472 (mCtx->channels != mNumChannels || mCtx->sample_rate != mSamplingRate)) {
473 LOGI("audio OMX_EventPortSettingsChanged, mCtx->channels: %d, mNumChannels: %d, mCtx->sample_rate: %d, mSamplingRate: %d",
474 mCtx->channels, mNumChannels, mCtx->sample_rate, mSamplingRate);
475 mCtx->channels = mNumChannels;
476 mCtx->sample_rate = mSamplingRate;
478 mAudioConfigChanged = true;
479 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
480 mOutputPortSettingsChange = AWAITING_DISABLED;
485 if (inHeader && inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
486 inQueue.erase(inQueue.begin());
487 inInfo->mOwnedByUs = false;
488 notifyEmptyBufferDone(inHeader);
492 if (mReceivedEOS && (mFlushComplete || !(mCtx->codec->capabilities & CODEC_CAP_DELAY))) {
493 outHeader->nFilledLen = 0;
494 outHeader->nFlags = OMX_BUFFERFLAG_EOS;
496 outQueue.erase(outQueue.begin());
497 outInfo->mOwnedByUs = false;
498 notifyFillBufferDone(outHeader);
502 if (inHeader && inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
503 LOGI("got extradata, ignore: %d, size: %lu", mIgnoreExtradata, inHeader->nFilledLen);
504 hexdump(inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
505 if (!mExtradataReady && !mIgnoreExtradata) {
506 int orig_extradata_size = mCtx->extradata_size;
507 mCtx->extradata_size += inHeader->nFilledLen;
508 mCtx->extradata = (uint8_t *)realloc(mCtx->extradata,
509 mCtx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
510 if (!mCtx->extradata) {
511 LOGE("ffmpeg audio decoder failed to alloc extradata memory.");
512 notify(OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
513 mSignalledError = true;
517 memcpy(mCtx->extradata + orig_extradata_size,
518 inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
519 memset(mCtx->extradata + mCtx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
521 inInfo->mOwnedByUs = false;
522 inQueue.erase(inQueue.begin());
524 notifyEmptyBufferDone(inHeader);
529 if (mIgnoreExtradata) {
530 LOGI("got extradata, size: %lu, but ignore it", inHeader->nFilledLen);
531 inInfo->mOwnedByUs = false;
532 inQueue.erase(inQueue.begin());
534 notifyEmptyBufferDone(inHeader);
542 if (!mExtradataReady && !mIgnoreExtradata) {
543 LOGI("extradata is ready");
544 hexdump(mCtx->extradata, mCtx->extradata_size);
545 mExtradataReady = true;
547 LOGI("open ffmpeg decoder now");
549 err = avcodec_open2(mCtx, mCtx->codec, NULL);
551 LOGE("ffmpeg audio decoder failed to initialize. (%d)", err);
552 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
553 mSignalledError = true;
559 /* update the audio clock with the pts */
560 if (inHeader && inHeader->nOffset == 0) {
561 mAnchorTimeUs = inHeader->nTimeStamp;
562 mNumFramesOutput = 0;
563 mInputBufferSize = inHeader->nFilledLen;
566 if (inHeader && mAudioBufferSize == 0 && !mFlushComplete) {
568 av_init_packet(&pkt);
569 if (!mFlushComplete) {
570 pkt.data = (uint8_t *)inHeader->pBuffer + inHeader->nOffset;
571 pkt.size = inHeader->nFilledLen;
572 pkt.pts = inHeader->nTimeStamp; // ingore it, we will compute it
576 pkt.pts = AV_NOPTS_VALUE;
579 LOGV("pkt size: %d, pts: %lld", pkt.size, pkt.pts);
582 if (!(mFrame = avcodec_alloc_frame())) {
583 LOGE("ffmpeg audio decoder failed to alloc memory.");
584 notify(OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
585 mSignalledError = true;
589 avcodec_get_frame_defaults(mFrame);
593 inputBufferUsedLength = 0;
594 len = avcodec_decode_audio4(mCtx, mFrame, &gotFrm, &pkt);
596 LOGE("ffmpeg audio decoder failed to decode frame. (0x%x)", len);
598 /* if !mAudioConfigChanged, Don't fill the out buffer */
599 if (!mAudioConfigChanged) {
600 inInfo->mOwnedByUs = false;
601 inQueue.erase(inQueue.begin());
603 notifyEmptyBufferDone(inHeader);
608 inputBufferUsedLength = inHeader->nFilledLen;
609 /* if error, we skip the frame and play silence instead */
610 mPAudioBuffer = mSilenceBuffer;
611 mAudioBufferSize = kOutputBufferSize;
612 } else if (!gotFrm) {
613 LOGI("ffmpeg audio decoder failed to get frame.");
614 /* stop sending empty packets if the decoder is finished */
615 if (!pkt.data && mCtx->codec->capabilities & CODEC_CAP_DELAY)
616 mFlushComplete = true;
620 * FIXME, check mAudioConfigChanged when the first time you call the audio4!
621 * mCtx->sample_rate and mCtx->channels may be changed by audio decoder later, why???
623 if (!mAudioConfigChanged) {
624 if (mCtx->channels != mNumChannels || mCtx->sample_rate != mSamplingRate) {
625 LOGI("audio OMX_EventPortSettingsChanged, mCtx->channels: %d, mNumChannels: %d, mCtx->sample_rate: %d, mSamplingRate: %d",
626 mCtx->channels, mNumChannels, mCtx->sample_rate, mSamplingRate);
627 mNumChannels = mCtx->channels;
628 mSamplingRate = mCtx->sample_rate;
629 mAudioConfigChanged = true;
630 notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
631 mOutputPortSettingsChange = AWAITING_DISABLED;
634 // match with the default, set mAudioConfigChanged true anyway!
635 mAudioConfigChanged = true;
639 inputBufferUsedLength = len;
640 mPAudioBuffer = mFrame->data[0];
641 mAudioBufferSize = av_samples_get_buffer_size(NULL, mCtx->channels,
643 mCtx->sample_fmt, 1);
644 LOGV("ffmpeg audio decoder get frame. (%d), mAudioBufferSize: %d", len, mAudioBufferSize);
648 size_t copyToOutputBufferLen = mAudioBufferSize;
649 if (mAudioBufferSize > kOutputBufferSize)
650 copyToOutputBufferLen = kOutputBufferSize;
652 outHeader->nOffset = 0;
653 outHeader->nFilledLen = copyToOutputBufferLen;
654 outHeader->nTimeStamp = mAnchorTimeUs
655 + (mNumFramesOutput * 1000000ll) / mSamplingRate;
656 memcpy(outHeader->pBuffer, mPAudioBuffer, copyToOutputBufferLen);
657 outHeader->nFlags = 0;
659 mPAudioBuffer += copyToOutputBufferLen;
660 mAudioBufferSize -= copyToOutputBufferLen;
661 mNumFramesOutput += copyToOutputBufferLen / av_get_bytes_per_sample(mCtx->sample_fmt) / mNumChannels;
664 CHECK_GE(inHeader->nFilledLen, inputBufferUsedLength);
665 inHeader->nOffset += inputBufferUsedLength;
666 inHeader->nFilledLen -= inputBufferUsedLength;
667 mInputBufferSize -= inputBufferUsedLength;
668 if (inHeader->nFilledLen == 0) {
669 inInfo->mOwnedByUs = false;
670 inQueue.erase(inQueue.begin());
672 notifyEmptyBufferDone(inHeader);
675 mInputBufferSize = 0;
679 outInfo->mOwnedByUs = false;
680 outQueue.erase(outQueue.begin());
682 notifyFillBufferDone(outHeader);
687 void SoftFFmpegAudio::onPortFlushCompleted(OMX_U32 portIndex) {
688 if (portIndex == 0 && mCtx) {
689 // Make sure that the next buffer output does not still
690 // depend on fragments from the last one decoded.
691 avcodec_flush_buffers(mCtx);
696 void SoftFFmpegAudio::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
697 if (portIndex != 1) {
701 switch (mOutputPortSettingsChange) {
705 case AWAITING_DISABLED:
708 mOutputPortSettingsChange = AWAITING_ENABLED;
714 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
716 mOutputPortSettingsChange = NONE;
722 } // namespace android
724 android::SoftOMXComponent *createSoftOMXComponent(
725 const char *name, const OMX_CALLBACKTYPE *callbacks,
726 OMX_PTR appData, OMX_COMPONENTTYPE **component) {
727 return new android::SoftFFmpegAudio(name, callbacks, appData, component);