Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 625c9f17 authored by Christopher N. Hesse's avatar Christopher N. Hesse Committed by Gerrit Code Review
Browse files

stagefright: Add support for Exynos hardware audio decoding

This patch includes support for Exynos AAC and MP3 decoders.

The following edits are needed as well, but not included in this
commit because CM already had them:

1) http://review.cyanogenmod.org/#/c/105520/11/media/libstagefright/AudioPlayer.cpp (line 529)
2) http://review.cyanogenmod.org/#/c/105520/11/media/libstagefright/OMXCodec.cpp (line 3290)
3) http://review.cyanogenmod.org/#/c/105520/11/media/libstagefright/StagefrightMediaScanner.cpp (line 51)

Taken from Hardkernel:
https://github.com/codewalkerster/android_frameworks_av/commit/dcd507cdb113b939967247afa31cd777ea34c43d

Change-Id: I555100c4afb73b56485873976e5bdb6b0605c58b
parent b8745714
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -166,6 +166,10 @@ private:

    AudioPlayer(const AudioPlayer &);
    AudioPlayer &operator=(const AudioPlayer &);

#ifdef USE_ALP_AUDIO
    bool mIsALPAudio;
#endif
};

}  // namespace android
+8 −0
Original line number Diff line number Diff line
@@ -243,6 +243,14 @@ endif
LOCAL_C_INCLUDES += \
	$(TOP)/external/stagefright-plugins/include

ifeq ($(BOARD_USE_ALP_AUDIO),  true)
LOCAL_CFLAGS += -DUSE_ALP_AUDIO
endif

ifeq ($(BOARD_USE_SEIREN_AUDIO), true)
LOCAL_CFLAGS += -DUSE_SEIREN_AUDIO
endif

LOCAL_MODULE:= libstagefright

LOCAL_MODULE_TAGS := optional
+30 −0
Original line number Diff line number Diff line
@@ -104,6 +104,10 @@ AudioPlayer::AudioPlayer(
#endif //DOLBY_END
      mPauseRequired(false),
      mUseSmallBufs(false) {
#ifdef USE_ALP_AUDIO
      mSeekTimeUs = 0;
      mIsALPAudio = false;
#endif
}

AudioPlayer::~AudioPlayer() {
@@ -188,6 +192,15 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
    success = format->findInt32(kKeyChannelCount, &numChannels);
    CHECK(success);

#ifdef USE_ALP_AUDIO
    const char *componentName;
    if (format->findCString(kKeyDecoderComponent, &componentName) == true) {
        if (strcmp(componentName, "OMX.Exynos.MP3.Decoder") == 0) {
            mIsALPAudio = true;
        }
    }
#endif

    format->findInt64(kKeyDuration, &mDurationUs);

    if(!format->findInt32(kKeyChannelMask, &channelMask)) {
@@ -346,7 +359,9 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
    updateDolbyProcessedAudioState();
#endif // DOLBY_END
    mPinnedTimeUs = -1ll;
#ifndef USE_ALP_AUDIO
    const char *componentName;
#endif
    if (!(format->findCString(kKeyDecoderComponent, &componentName))) {
          componentName = "none";
    }
@@ -805,7 +820,11 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {
                // and mPositionTimeRealUs
                // before clearing mSeekTimeUs check if a new seek request has been received while
                // we were reading from the source with mLock released.
#ifdef USE_ALP_AUDIO
                if (!mSeeking && !mIsALPAudio) {
#else
                if (!mSeeking) {
#endif
                    mSeekTimeUs = 0;
                }
            }
@@ -979,7 +998,18 @@ int64_t AudioPlayer::getMediaTimeUs() {
        return 0;
    }

#ifdef USE_ALP_AUDIO
    /*
     * Audio timestamp should be calculated not by input streams
     * passed to the mp3 decoder but by played output frames.
     */
    if (mIsALPAudio)
        return mSeekTimeUs + mPositionTimeRealUs + realTimeOffset;
    else
        return mPositionTimeMediaUs + realTimeOffset;
#else
    return mPositionTimeMediaUs + realTimeOffset;
#endif
}

bool AudioPlayer::getMediaTimeMapping(
+28 −0
Original line number Diff line number Diff line
@@ -2003,6 +2003,34 @@ status_t AwesomePlayer::initAudioDecoder() {
    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
        ALOGV("createAudioPlayer: bypass OMX (raw)");
        mAudioSource = mAudioTrack;
#ifdef USE_ALP_AUDIO
     } else if (mVideoTrack == NULL && !strncasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG, 10)) {
        mAudioSource = OMXCodec::Create(
            mClient.interface(), mAudioTrack->getFormat(),
            false,  // createEncoder
            mAudioTrack,
            "OMX.Exynos.MP3.Decoder");
        if (mAudioSource == NULL) {
            mAudioSource = OMXCodec::Create(
                    mClient.interface(), mAudioTrack->getFormat(),
                    false,  // createEncoder
                    mAudioTrack);
        }
#endif
#ifdef USE_SEIREN_AUDIO
     } else if (mVideoTrack == NULL && !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
        mAudioSource = OMXCodec::Create(
            mClient.interface(), mAudioTrack->getFormat(),
            false,  // createEncoder
            mAudioTrack,
            "OMX.Exynos.AAC.Decoder");
        if (mAudioSource == NULL) {
            mAudioSource = OMXCodec::Create(
                    mClient.interface(), mAudioTrack->getFormat(),
                    false,  // createEncoder
                    mAudioTrack);
        }
#endif
        // For PCM offload fallback
        if (mOffloadAudio) {
            mOmxSource = mAudioSource;
+47 −0
Original line number Diff line number Diff line
@@ -430,6 +430,27 @@ uint32_t OMXCodec::getComponentQuirks(
    }
#endif // DOLBY_END

#ifdef USE_ALP_AUDIO
    /*
     * Exynos Mp3 decoder needs the following quirks.
     *
     * kSupportsMultipleFramesPerInputBuffer :
     *         To coalesce as much as SRP's input buffer size
     * kNeedsFlushBeforeDisable :
     *         Flush is necessary before port is disabled.
     */
    if (!strcmp("OMX.Exynos.MP3.Decoder", info->getCodecName())) {
        quirks |= kSupportsMultipleFramesPerInputBuffer;
        quirks |= kNeedsFlushBeforeDisable;
    }
#endif
#ifdef USE_SEIREN_AUDIO
    if (!strcmp("OMX.Exynos.AAC.Decoder", info->getCodecName())) {
        quirks |= kSupportsMultipleFramesPerInputBuffer;
        quirks |= kNeedsFlushBeforeDisable;
    }
#endif

    return quirks;
}

@@ -3592,10 +3613,18 @@ void OMXCodec::fillOutputBuffers() {
                == mPortBuffers[kPortIndexInput].size()
            && countBuffersWeOwn(mPortBuffers[kPortIndexOutput])
                == mPortBuffers[kPortIndexOutput].size()) {
#ifdef USE_ALP_AUDIO
        /* Exynos mp3 decoder should be finished by EOS flag in output buffer. */
        /* Do not apply this workaround */
        if (strcmp(mComponentName, "OMX.Exynos.MP3.Decoder") != 0) {
#endif
        mNoMoreOutputData = true;
        mBufferFilled.signal();

        return;
#ifdef USE_ALP_AUDIO
        }
#endif
    }

    Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexOutput];
@@ -3915,12 +3944,30 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) {
            break;
        }

#ifdef USE_ALP_AUDIO
#ifndef USE_SEIREN_AUDIO
        /*
         * In ALP mode, 250ms restriction is not required.
         * SRP driver must have enough frames for the size of its input buffer.
         */
        if (strcmp(mComponentName, "OMX.Exynos.MP3.Decoder") != 0) {
#endif
#endif
        int64_t coalescedDurationUs = lastBufferTimeUs - timestampUs;

#ifdef USE_SEIREN_AUDIO
        if (coalescedDurationUs > 150000ll) {
#else
        if (coalescedDurationUs > 250000ll) {
#endif
            // Don't coalesce more than 250ms worth of encoded data at once.
            break;
        }
#ifdef USE_ALP_AUDIO
#ifndef USE_SEIREN_AUDIO
        }
#endif
#endif
    }

    if (n > 1) {