OSDN Git Service

Merge branch 'lollipop-x86' into multiwindow-hwaccel
[android-x86/external-stagefright-plugins.git] / omx / SoftFFmpegAudio.cpp
index 2ecdb17..43ac9d9 100644 (file)
@@ -15,7 +15,6 @@
  * limitations under the License.
  */
 
-//#define LOG_NDEBUG 0
 #define LOG_TAG "SoftFFmpegAudio"
 #include <utils/Log.h>
 #include <cutils/properties.h>
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/ACodec.h>
 #include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/OMXCodec.h>
 
 #include <OMX_AudioExt.h>
 #include <OMX_IndexExt.h>
 
 #define DEBUG_PKT 0
 #define DEBUG_FRM 0
+#define DEBUG_EXTRADATA 0
 
 namespace android {
 
 template<class T>
 static void InitOMXParams(T *params) {
+    memset(params, 0, sizeof(T));
     params->nSize = sizeof(T);
     params->nVersion.s.nVersionMajor = 1;
     params->nVersion.s.nVersionMinor = 0;
@@ -75,12 +76,8 @@ SoftFFmpegAudio::SoftFFmpegAudio(
 
     setAudioClock(0);
 
-    char value[PROPERTY_VALUE_MAX] = {0};
-    property_get("audio.offload.24bit.enable", value, "1");
-    mHighResAudioEnabled = atoi(value);
-
-    ALOGD("SoftFFmpegAudio component: %s mCodingType: %d mHighResAudioEnabled: %d",
-            name, mCodingType, mHighResAudioEnabled);
+    ALOGD("SoftFFmpegAudio component: %s mCodingType: %d",
+            name, mCodingType);
 
     initPorts();
     CHECK_EQ(initDecoder(codecID), (status_t)OK);
@@ -109,7 +106,7 @@ void SoftFFmpegAudio::initPorts() {
         def.nBufferSize = 1000000; // dts!
     } else {
         // max aggregated buffer size from nuplayer
-        def.nBufferSize = 24 * 1024;
+        def.nBufferSize = 32 * 1024;
     }
 
     def.bEnabled = OMX_TRUE;
@@ -148,24 +145,19 @@ void SoftFFmpegAudio::setDefaultCtx(AVCodecContext *avctx, const AVCodec *codec)
     int fast = 0;
 
     avctx->workaround_bugs   = 1;
-    avctx->lowres            = 0;
-    if(avctx->lowres > codec->max_lowres){
-        ALOGW("The maximum value for lowres supported by the decoder is %d",
-                codec->max_lowres);
-        avctx->lowres= codec->max_lowres;
-    }
     avctx->idct_algo         = 0;
     avctx->skip_frame        = AVDISCARD_DEFAULT;
     avctx->skip_idct         = AVDISCARD_DEFAULT;
     avctx->skip_loop_filter  = AVDISCARD_DEFAULT;
     avctx->error_concealment = 3;
 
-    avctx->flags |= CODEC_FLAG_BITEXACT;
+    avctx->flags |= AV_CODEC_FLAG_BITEXACT;
 
-    if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
-    if (fast)   avctx->flags2 |= CODEC_FLAG2_FAST;
-    if(codec->capabilities & CODEC_CAP_DR1)
+    if (fast) avctx->flags2 |= AV_CODEC_FLAG2_FAST;
+#ifdef CODEC_FLAG_EMU_EDGE
+    if (codec->capabilities & AV_CODEC_CAP_DR1)
         avctx->flags |= CODEC_FLAG_EMU_EDGE;
+#endif
 }
 
 bool SoftFFmpegAudio::isConfigured() {
@@ -247,18 +239,22 @@ void SoftFFmpegAudio::deInitDecoder() {
 
         if (mCodecAlreadyOpened) {
             avcodec_close(mCtx);
-            av_free(mCtx);
-            mCtx = NULL;
+            mCodecAlreadyOpened = false;
         }
+        av_free(mCtx);
+        mCtx = NULL;
     }
     if (mFrame) {
-        av_freep(&mFrame);
+        av_frame_free(&mFrame);
         mFrame = NULL;
     }
+#ifdef LIBAV_CONFIG_H
+#else
     if (mSwrCtx) {
         swr_free(&mSwrCtx);
         mSwrCtx = NULL;
     }
+#endif
 }
 
 OMX_ERRORTYPE SoftFFmpegAudio::internalGetParameter(
@@ -278,14 +274,31 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalGetParameter(
             profile->eEndian = OMX_EndianBig;
             profile->bInterleaved = OMX_TRUE;
             profile->ePCMMode = OMX_AUDIO_PCMModeLinear;
+                       profile->nBitPerSample = 32;
+            profile->eNumData = OMX_NumericalDataFloat;
 
             if (isConfigured()) {
-                profile->nBitPerSample = av_get_bytes_per_sample(mAudioTgtFmt) > 2 ? 24 : 16;
-            } else {
-                profile->nBitPerSample = mHighResAudioEnabled ? 24 : 16;
+                switch (av_get_packed_sample_fmt(mAudioTgtFmt)) {
+                    case AV_SAMPLE_FMT_U8:
+                        profile->nBitPerSample = 8;
+                        profile->eNumData = OMX_NumericalDataUnsigned;
+                        break;
+                    case AV_SAMPLE_FMT_S16:
+                        profile->nBitPerSample = 16;
+                        profile->eNumData = OMX_NumericalDataSigned;
+                        break;
+                    case AV_SAMPLE_FMT_S32:
+                        profile->nBitPerSample = 32;
+                        profile->eNumData = OMX_NumericalDataSigned;
+                        break;
+                    default:
+                        profile->nBitPerSample = 32;
+                        profile->eNumData = OMX_NumericalDataFloat;
+                        break;
+                }
             }
 
-            if (getOMXChannelMapping(mAudioTgtChannels, profile->eChannelMapping) != OK) {
+            if (ACodec::getOMXChannelMapping(mAudioTgtChannels, profile->eChannelMapping) != OK) {
                 return OMX_ErrorNone;
             }
 
@@ -293,7 +306,7 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalGetParameter(
             profile->nSamplingRate = mAudioTgtFreq;
 
             //mCtx has been updated(adjustAudioParams)!
-            ALOGV("get pcm params, nChannels:%lu, nSamplingRate:%lu, nBitsPerSample:%lu",
+            ALOGV("get pcm params, nChannels:%u, nSamplingRate:%u, nBitPerSample:%u",
                    profile->nChannels, profile->nSamplingRate, profile->nBitPerSample);
 
             return OMX_ErrorNone;
@@ -414,7 +427,7 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalGetParameter(
 
             profile->nChannels = mCtx->channels;
             profile->nSampleRate = mCtx->sample_rate;
-
+            profile->nCompressionLevel = mCtx->bits_per_raw_sample;
             return OMX_ErrorNone;
         }
 
@@ -464,6 +477,23 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalGetParameter(
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioAlac:
+        {
+            OMX_AUDIO_PARAM_ALACTYPE *profile =
+                (OMX_AUDIO_PARAM_ALACTYPE *)params;
+
+            if (profile->nPortIndex != kInputPortIndex) {
+                return OMX_ErrorUndefined;
+            }
+
+            profile->nChannels = mCtx->channels;
+            profile->nSamplingRate = mCtx->sample_rate;
+
+            profile->nBitsPerSample = mCtx->bits_per_coded_sample;
+
+            return OMX_ErrorNone;
+        }
+
         case OMX_IndexParamAudioApe:
         {
             OMX_AUDIO_PARAM_APETYPE *profile =
@@ -539,20 +569,13 @@ OMX_ERRORTYPE SoftFFmpegAudio::isRoleSupported(
 
 void SoftFFmpegAudio::adjustAudioParams() {
 
-    uint32_t max_rate = 48000;
-
     mReconfiguring = isConfigured();
 
     // let android audio mixer to downmix if there is no multichannel output
     // and use number of channels from the source file, useful for HDMI/offload output
     mAudioTgtChannels = mCtx->channels;
 
-    // 4000 <= sampling rate <= 48000/192000
-    if (mHighResAudioEnabled) {
-        max_rate = 192000;
-    }
-
-    mAudioTgtFreq = FFMIN(max_rate, FFMAX(8000, mCtx->sample_rate));
+    mAudioTgtFreq = FFMIN(192000, FFMAX(8000, mCtx->sample_rate));
 
     mAudioTgtChannels = mCtx->channels;
     mAudioTgtFreq = mCtx->sample_rate;
@@ -583,18 +606,33 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
                 return OMX_ErrorUndefined;
             }
 
-            if (mHighResAudioEnabled &&
-                    (profile->nBitPerSample > 16 || profile->nBitPerSample == 0)) {
-                mAudioTgtFmt = AV_SAMPLE_FMT_S32;
-            } else {
-                mAudioTgtFmt = AV_SAMPLE_FMT_S16;
+            switch (profile->nBitPerSample) {
+                case 8:
+                    mAudioTgtFmt = AV_SAMPLE_FMT_U8;
+                    break;
+                case 16:
+                    mAudioTgtFmt = AV_SAMPLE_FMT_S16;
+                    break;
+                case 24:
+                    mAudioTgtFmt = AV_SAMPLE_FMT_S32;
+                    break;
+                case 32:
+                    if (profile->eNumData == OMX_NumericalDataFloat) {
+                        mAudioTgtFmt = AV_SAMPLE_FMT_FLT;
+                        break;
+                    }
+                    mAudioTgtFmt = AV_SAMPLE_FMT_S32;
+                    break;
+                default:
+                    ALOGE("Unknown PCM encoding, assuming floating point");
+                    mAudioTgtFmt = AV_SAMPLE_FMT_FLT;
             }
 
             mAudioTgtFreq = profile->nSamplingRate;
             mAudioTgtChannels = profile->nChannels;
 
-            ALOGV("set OMX_IndexParamAudioPcm, nChannels:%lu, "
-                    "nSampleRate:%lu, nBitsPerSample:%lu",
+            ALOGV("set OMX_IndexParamAudioPcm, nChannels:%u, "
+                    "nSampleRate:%u, nBitPerSample:%u",
                 profile->nChannels, profile->nSamplingRate,
                 profile->nBitPerSample);
 
@@ -615,7 +653,7 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             adjustAudioParams();
 
-            ALOGV("set OMX_IndexParamAudioAac, nChannels:%lu, nSampleRate:%lu",
+            ALOGV("set OMX_IndexParamAudioAac, nChannels:%u, nSampleRate:%u",
                 profile->nChannels, profile->nSampleRate);
 
             return OMX_ErrorNone;
@@ -635,7 +673,7 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             adjustAudioParams();
 
-            ALOGV("set OMX_IndexParamAudioMp3, nChannels:%lu, nSampleRate:%lu",
+            ALOGV("set OMX_IndexParamAudioMp3, nChannels:%u, nSampleRate:%u",
                 profile->nChannels, profile->nSampleRate);
 
             return OMX_ErrorNone;
@@ -656,8 +694,8 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
             adjustAudioParams();
 
             ALOGD("set OMX_IndexParamAudioVorbis, "
-                    "nChannels=%lu, nSampleRate=%lu, nBitRate=%lu, "
-                    "nMinBitRate=%lu, nMaxBitRate=%lu",
+                    "nChannels=%u, nSampleRate=%u, nBitRate=%u, "
+                    "nMinBitRate=%u, nMaxBitRate=%u",
                 profile->nChannels, profile->nSampleRate,
                 profile->nBitRate, profile->nMinBitRate,
                 profile->nMaxBitRate);
@@ -695,7 +733,7 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
             adjustAudioParams();
 
             ALOGV("set OMX_IndexParamAudioWma, nChannels:%u, "
-                    "nSampleRate:%lu, nBitRate:%lu, nBlockAlign:%u",
+                    "nSampleRate:%u, nBitRate:%u, nBlockAlign:%u",
                 profile->nChannels, profile->nSamplingRate,
                 profile->nBitRate, profile->nBlockAlign);
 
@@ -720,8 +758,8 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             adjustAudioParams();
 
-            ALOGV("set OMX_IndexParamAudioRa, nChannels:%lu, "
-                    "nSampleRate:%lu, nBlockAlign:%d",
+            ALOGV("set OMX_IndexParamAudioRa, nChannels:%u, "
+                    "nSampleRate:%u, nBlockAlign:%d",
                 profile->nChannels, profile->nSamplingRate, mCtx->block_align);
 
             return OMX_ErrorNone;
@@ -741,7 +779,7 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             adjustAudioParams();
 
-            ALOGV("set OMX_IndexParamAudioFlac, nChannels:%lu, nSampleRate:%lu ",
+            ALOGV("set OMX_IndexParamAudioFlac, nChannels:%u, nSampleRate:%u ",
                 profile->nChannels, profile->nSampleRate);
 
             return OMX_ErrorNone;
@@ -761,7 +799,7 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             adjustAudioParams();
 
-            ALOGV("set OMX_IndexParamAudioMp2, nChannels:%lu, nSampleRate:%lu",
+            ALOGV("set OMX_IndexParamAudioMp2, nChannels:%u, nSampleRate:%u",
                 profile->nChannels, profile->nSampleRate);
 
             return OMX_ErrorNone;
@@ -781,7 +819,7 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             adjustAudioParams();
 
-            ALOGV("set OMX_IndexParamAudioAc3, nChannels:%lu, nSampleRate:%lu",
+            ALOGV("set OMX_IndexParamAudioAc3, nChannels:%u, nSampleRate:%u",
                 profile->nChannels, profile->nSamplingRate);
 
             return OMX_ErrorNone;
@@ -801,12 +839,34 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             adjustAudioParams();
 
-            ALOGV("set OMX_IndexParamAudioAndroidAc3, nChannels:%lu, nSampleRate:%lu",
+            ALOGV("set OMX_IndexParamAudioAndroidAc3, nChannels:%u, nSampleRate:%u",
                 profile->nChannels, profile->nSampleRate);
 
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioAlac:
+        {
+            OMX_AUDIO_PARAM_ALACTYPE *profile =
+                (OMX_AUDIO_PARAM_ALACTYPE *)params;
+
+            if (profile->nPortIndex != kInputPortIndex) {
+                return OMX_ErrorUndefined;
+            }
+
+            mCtx->channels = profile->nChannels;
+            mCtx->sample_rate = profile->nSamplingRate;
+            mCtx->bits_per_coded_sample = profile->nBitsPerSample;
+
+            adjustAudioParams();
+
+            ALOGV("set OMX_IndexParamAudioAlac, nChannels:%u, "
+                    "nSampleRate:%u, nBitsPerSample:%u",
+                profile->nChannels, profile->nSamplingRate,
+                profile->nBitsPerSample);
+
+            return OMX_ErrorNone;
+        }
 
         case OMX_IndexParamAudioApe:
         {
@@ -823,8 +883,8 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             adjustAudioParams();
 
-            ALOGV("set OMX_IndexParamAudioApe, nChannels:%lu, "
-                    "nSampleRate:%lu, nBitsPerSample:%lu",
+            ALOGV("set OMX_IndexParamAudioApe, nChannels:%u, "
+                    "nSampleRate:%u, nBitsPerSample:%u",
                 profile->nChannels, profile->nSamplingRate,
                 profile->nBitsPerSample);
 
@@ -845,7 +905,7 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
 
             adjustAudioParams();
 
-            ALOGV("set OMX_IndexParamAudioDts, nChannels:%lu, nSampleRate:%lu",
+            ALOGV("set OMX_IndexParamAudioDts, nChannels:%u, nSampleRate:%u",
                 profile->nChannels, profile->nSamplingRate);
 
             return OMX_ErrorNone;
@@ -871,9 +931,9 @@ OMX_ERRORTYPE SoftFFmpegAudio::internalSetParameter(
             adjustAudioParams();
 
             ALOGD("set OMX_IndexParamAudioFFmpeg, "
-                "eCodecId:%ld(%s), nChannels:%lu, nBitRate:%lu, "
-                "nBitsPerSample:%lu, nSampleRate:%lu, "
-                "nBlockAlign:%lu, eSampleFormat:%lu(%s)",
+                "eCodecId:%d(%s), nChannels:%u, nBitRate:%u, "
+                "nBitsPerSample:%u, nSampleRate:%u, "
+                "nBlockAlign:%u, eSampleFormat:%u(%s)",
                 profile->eCodecId, avcodec_get_name(mCtx->codec_id),
                 profile->nChannels, profile->nBitRate,
                 profile->nBitsPerSample, profile->nSampleRate,
@@ -921,12 +981,14 @@ int32_t SoftFFmpegAudio::handleExtradata() {
     BufferInfo *inInfo = *inQueue.begin();
     OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
 
-    ALOGI("got extradata, ignore: %d, size: %lu",
+#if DEBUG_EXTRADATA
+    ALOGI("got extradata, ignore: %d, size: %u",
             mIgnoreExtradata, inHeader->nFilledLen);
     hexdump(inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
+#endif
 
     if (mIgnoreExtradata) {
-        ALOGI("got extradata, size: %lu, but ignore it", inHeader->nFilledLen);
+        ALOGI("got extradata, size: %u, but ignore it", inHeader->nFilledLen);
     } else {
         if (!mExtradataReady) {
             uint32_t ret = ERR_OK;
@@ -939,7 +1001,7 @@ int32_t SoftFFmpegAudio::handleExtradata() {
                 int orig_extradata_size = mCtx->extradata_size;
                 mCtx->extradata_size += inHeader->nFilledLen;
                 mCtx->extradata = (uint8_t *)av_realloc(mCtx->extradata,
-                    mCtx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+                    mCtx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
                 if (!mCtx->extradata) {
                     ALOGE("ffmpeg audio decoder failed to alloc extradata memory.");
                     return ERR_OOM;
@@ -947,7 +1009,7 @@ int32_t SoftFFmpegAudio::handleExtradata() {
 
                 memcpy(mCtx->extradata + orig_extradata_size,
                     inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
-                memset(mCtx->extradata + mCtx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+                memset(mCtx->extradata + mCtx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
             }
         }
     }
@@ -976,8 +1038,10 @@ int32_t SoftFFmpegAudio::openDecoder() {
             }
             deinitVorbisHdr();
         }
+#if DEBUG_EXTRADATA
         ALOGI("extradata is ready, size: %d", mCtx->extradata_size);
         hexdump(mCtx->extradata, mCtx->extradata_size);
+#endif
         mExtradataReady = true;
     }
 
@@ -1066,29 +1130,36 @@ int32_t SoftFFmpegAudio::decodeAudio() {
     int gotFrm = false;
     int32_t ret = ERR_OK;
     int32_t inputBufferUsedLength = 0;
-    bool is_flush = (mEOSStatus != INPUT_DATA_AVAILABLE);
+    bool is_flush = (mEOSStatus == OUTPUT_FRAMES_FLUSHED);
     List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
     BufferInfo *inInfo = NULL;
     OMX_BUFFERHEADERTYPE *inHeader = NULL;
 
     CHECK_EQ(mResampledDataSize, 0);
 
-    if (!is_flush) {
+    if (!is_flush && !inQueue.empty()) {
         inInfo = *inQueue.begin();
-        CHECK(inInfo != NULL);
-        inHeader = inInfo->mHeader;
+        if (inInfo != NULL)  {
+            inHeader = inInfo->mHeader;
 
-        if (mInputBufferSize == 0) {
-            updateTimeStamp(inHeader);
-            mInputBufferSize = inHeader->nFilledLen;
+            if (mInputBufferSize == 0) {
+                updateTimeStamp(inHeader);
+                mInputBufferSize = inHeader->nFilledLen;
+            }
         }
     }
 
+    if (mEOSStatus == INPUT_EOS_SEEN && (!inHeader || inHeader->nFilledLen == 0)
+        && !(mCtx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
+        return ERR_FLUSHED;
+    }
+
     AVPacket pkt;
     initPacket(&pkt, inHeader);
-    av_frame_unref(mFrame);
 
     len = avcodec_decode_audio4(mCtx, mFrame, &gotFrm, &pkt);
+    av_packet_unref(&pkt);
+
     //a negative error code is returned if an error occurred during decoding
     if (len < 0) {
         ALOGW("ffmpeg audio decoder err, we skip the frame and play silence instead");
@@ -1104,7 +1175,7 @@ int32_t SoftFFmpegAudio::decodeAudio() {
             ALOGI("ffmpeg audio decoder failed to get frame.");
 #endif
             //stop sending empty packets if the decoder is finished
-            if (is_flush && mCtx->codec->capabilities & CODEC_CAP_DELAY) {
+            if (is_flush && mCtx->codec->capabilities & AV_CODEC_CAP_DELAY) {
                 ALOGI("ffmpeg audio decoder failed to get more frames when flush.");
                 ret = ERR_FLUSHED;
             } else {
@@ -1122,23 +1193,29 @@ int32_t SoftFFmpegAudio::decodeAudio() {
         } else {
             inputBufferUsedLength = len;
         }
-
-        CHECK_GE(inHeader->nFilledLen, inputBufferUsedLength);
-        inHeader->nOffset += inputBufferUsedLength;
-        inHeader->nFilledLen -= inputBufferUsedLength;
         mInputBufferSize -= inputBufferUsedLength;
 
-        if (inHeader->nFilledLen == 0) {
-            CHECK_EQ(mInputBufferSize, 0);
-            inQueue.erase(inQueue.begin());
-            inInfo->mOwnedByUs = false;
-            notifyEmptyBufferDone(inHeader);
+        if (inHeader != NULL) {
+            CHECK_GE(inHeader->nFilledLen, inputBufferUsedLength);
+            inHeader->nOffset += inputBufferUsedLength;
+            inHeader->nFilledLen -= inputBufferUsedLength;
+
+            if (inHeader->nFilledLen == 0) {
+                CHECK_EQ(mInputBufferSize, 0);
+                inQueue.erase(inQueue.begin());
+                inInfo->mOwnedByUs = false;
+                notifyEmptyBufferDone(inHeader);
+            }
         }
     }
 
     return ret;
 }
 
+#ifdef LIBAV_CONFIG_H
+#define av_frame_get_channels(f) av_get_channel_layout_nb_channels(f->channel_layout)
+#endif
+
 int32_t SoftFFmpegAudio::resampleAudio() {
     int channels = 0;
     int64_t channelLayout = 0;
@@ -1166,6 +1243,9 @@ int32_t SoftFFmpegAudio::resampleAudio() {
                 || mAudioSrcFmt != mAudioTgtFmt
                 || mAudioSrcChannelLayout != mAudioTgtChannelLayout
                 || mAudioSrcFreq != mAudioTgtFreq))) {
+#ifdef LIBAV_CONFIG_H
+        if (!mSwrCtx) {
+#else
         if (mSwrCtx) {
             swr_free(&mSwrCtx);
         }
@@ -1174,6 +1254,7 @@ int32_t SoftFFmpegAudio::resampleAudio() {
                 channelLayout,       (enum AVSampleFormat)mFrame->format, mFrame->sample_rate,
                 0, NULL);
         if (!mSwrCtx || swr_init(mSwrCtx) < 0) {
+#endif
             ALOGE("Cannot create sample rate converter for conversion "
                     "of %d Hz %s %d channels to %d Hz %s %d channels!",
                     mFrame->sample_rate,
@@ -1211,6 +1292,8 @@ int32_t SoftFFmpegAudio::resampleAudio() {
     }
 
     if (mSwrCtx) {
+#ifdef LIBAV_CONFIG_H
+#else
         const uint8_t **in = (const uint8_t **)mFrame->extended_data;
         uint8_t *out[] = {mAudioBuffer};
         int out_count = sizeof(mAudioBuffer) / mAudioTgtChannels / av_get_bytes_per_sample(mAudioTgtFmt);
@@ -1242,6 +1325,7 @@ int32_t SoftFFmpegAudio::resampleAudio() {
                 mAudioTgtChannels,
                 av_get_sample_fmt_name(mAudioTgtFmt));
 #endif
+#endif
     } else {
         mResampledData = mFrame->data[0];
         mResampledDataSize = dataSize;
@@ -1330,12 +1414,6 @@ void SoftFFmpegAudio::drainAllOutputBuffers() {
         return;
     }
 
-    if(!(mCtx->codec->capabilities & CODEC_CAP_DELAY)) {
-        drainEOSOutputBuffer();
-        mEOSStatus = OUTPUT_FRAMES_FLUSHED;
-        return;
-    }
-
     while (!outQueue.empty()) {
         if (mResampledDataSize == 0) {
             int32_t err = decodeAudio();
@@ -1384,10 +1462,7 @@ void SoftFFmpegAudio::onQueueFilled(OMX_U32 /* portIndex */) {
         inHeader = inInfo->mHeader;
 
         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
-            ALOGD("ffmpeg audio decoder empty eos inbuf");
-            inQueue.erase(inQueue.begin());
-            inInfo->mOwnedByUs = false;
-            notifyEmptyBufferDone(inHeader);
+            ALOGD("ffmpeg audio decoder eos");
             mEOSStatus = INPUT_EOS_SEEN;
             continue;
         }
@@ -1430,9 +1505,9 @@ void SoftFFmpegAudio::onQueueFilled(OMX_U32 /* portIndex */) {
 }
 
 void SoftFFmpegAudio::onPortFlushCompleted(OMX_U32 portIndex) {
-    ALOGV("ffmpeg audio decoder flush port(%lu)", portIndex);
+    ALOGV("ffmpeg audio decoder flush port(%u)", portIndex);
     if (portIndex == kInputPortIndex) {
-        if (mCtx && mCtx->codec) {
+        if (mCtx && avcodec_is_open(mCtx)) {
             //Make sure that the next buffer output does not still
             //depend on fragments from the last one decoded.
             avcodec_flush_buffers(mCtx);
@@ -1477,7 +1552,7 @@ int64_t SoftFFmpegAudio::getAudioClock() {
         sAudioClock = (int64_t*) malloc(sizeof(int64_t));
         *sAudioClock = 0;
     }
-    ALOGV("getAudioClock: %lld", *sAudioClock);
+    ALOGV("getAudioClock: %" PRId64, *sAudioClock);
     return *sAudioClock;
 }
 
@@ -1494,6 +1569,7 @@ void SoftFFmpegAudio::onReset() {
     initDecoder(codecID);
     mSignalledError = false;
     mOutputPortSettingsChange = NONE;
+    mEOSStatus = INPUT_DATA_AVAILABLE;
 }
 
 SoftOMXComponent* SoftFFmpegAudio::createSoftOMXComponent(