/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "SoundPool::Sound"
#include <utils/Log.h>

#include "Sound.h"

#include <media/NdkMediaCodec.h>
#include <media/NdkMediaExtractor.h>
#include <media/NdkMediaFormat.h>

namespace android::soundpool {

constexpr uint32_t kMaxSampleRate = 192000;
constexpr size_t   kDefaultHeapSize = 1024 * 1024; // 1MB (compatible with low mem devices)

Sound::Sound(int32_t soundID, int fd, int64_t offset, int64_t length)
    : mSoundID(soundID)
    , mFd(dup(fd))
    , mOffset(offset)
    , mLength(length)
{
    ALOGV("%s(soundID=%d, fd=%d, offset=%lld, length=%lld)",
            __func__, soundID, fd, (long long)offset, (long long)length);
    ALOGW_IF(mFd == -1, "Unable to dup descriptor %d", fd);
}

Sound::~Sound()
{
    ALOGV("%s(soundID=%d, fd=%d)", __func__, mSoundID, mFd.get());
}

static status_t decode(int fd, int64_t offset, int64_t length,
        uint32_t *rate, int32_t *channelCount, audio_format_t *audioFormat,
        audio_channel_mask_t *channelMask, sp<MemoryHeapBase> heap,
        size_t *sizeInBytes) {
    ALOGV("%s(fd=%d, offset=%lld, length=%lld, ...)",
            __func__, fd, (long long)offset, (long long)length);
    std::unique_ptr<AMediaExtractor, decltype(&AMediaExtractor_delete)> ex{
            AMediaExtractor_new(), &AMediaExtractor_delete};
    status_t err = AMediaExtractor_setDataSourceFd(ex.get(), fd, offset, length);

    if (err != AMEDIA_OK) {
        return err;
    }

    *audioFormat = AUDIO_FORMAT_PCM_16_BIT;  // default format for audio codecs.
    const size_t numTracks = AMediaExtractor_getTrackCount(ex.get());
    for (size_t i = 0; i < numTracks; i++) {
        std::unique_ptr<AMediaFormat, decltype(&AMediaFormat_delete)> format{
                AMediaExtractor_getTrackFormat(ex.get(), i), &AMediaFormat_delete};
        const char *mime;
        if (!AMediaFormat_getString(format.get(),  AMEDIAFORMAT_KEY_MIME, &mime)) {
            return UNKNOWN_ERROR;
        }
        if (strncmp(mime, "audio/", 6) == 0) {
            std::unique_ptr<AMediaCodec, decltype(&AMediaCodec_delete)> codec{
                    AMediaCodec_createDecoderByType(mime), &AMediaCodec_delete};
            if (codec == nullptr
                    || AMediaCodec_configure(codec.get(), format.get(),
                            nullptr /* window */, nullptr /* drm */, 0 /* flags */) != AMEDIA_OK
                    || AMediaCodec_start(codec.get()) != AMEDIA_OK
                    || AMediaExtractor_selectTrack(ex.get(), i) != AMEDIA_OK) {
                return UNKNOWN_ERROR;
            }

            bool sawInputEOS = false;
            bool sawOutputEOS = false;
            uint8_t* writePos = static_cast<uint8_t*>(heap->getBase());
            size_t available = heap->getSize();
            size_t written = 0;
            format.reset(AMediaCodec_getOutputFormat(codec.get())); // update format.

            while (!sawOutputEOS) {
                if (!sawInputEOS) {
                    ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec.get(), 5000);
                    ALOGV("%s: input buffer %zd", __func__, bufidx);
                    if (bufidx >= 0) {
                        size_t bufsize;
                        uint8_t * const buf = AMediaCodec_getInputBuffer(
                                codec.get(), bufidx, &bufsize);
                        if (buf == nullptr) {
                            ALOGE("%s: AMediaCodec_getInputBuffer returned nullptr, short decode",
                                    __func__);
                            break;
                        }
                        int sampleSize = AMediaExtractor_readSampleData(ex.get(), buf, bufsize);
                        ALOGV("%s: read %d", __func__, sampleSize);
                        if (sampleSize < 0) {
                            sampleSize = 0;
                            sawInputEOS = true;
                            ALOGV("%s: EOS", __func__);
                        }
                        const int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex.get());

                        const media_status_t mstatus = AMediaCodec_queueInputBuffer(
                                codec.get(), bufidx,
                                0 /* offset */, sampleSize, presentationTimeUs,
                                sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0);
                        if (mstatus != AMEDIA_OK) {
                            // AMEDIA_ERROR_UNKNOWN == { -ERANGE -EINVAL -EACCES }
                            ALOGE("%s: AMediaCodec_queueInputBuffer returned status %d,"
                                    "short decode",
                                    __func__, (int)mstatus);
                            break;
                        }
                        (void)AMediaExtractor_advance(ex.get());
                    }
                }

                AMediaCodecBufferInfo info;
                const int status = AMediaCodec_dequeueOutputBuffer(codec.get(), &info, 1);
                ALOGV("%s: dequeueoutput returned: %d", __func__, status);
                if (status >= 0) {
                    if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
                        ALOGV("%s: output EOS", __func__);
                        sawOutputEOS = true;
                    }
                    ALOGV("%s: got decoded buffer size %d", __func__, info.size);

                    const uint8_t * const buf = AMediaCodec_getOutputBuffer(
                            codec.get(), status, nullptr /* out_size */);
                    if (buf == nullptr) {
                        ALOGE("%s: AMediaCodec_getOutputBuffer returned nullptr, short decode",
                                __func__);
                        break;
                    }
                    const size_t dataSize = std::min((size_t)info.size, available);
                    memcpy(writePos, buf + info.offset, dataSize);
                    writePos += dataSize;
                    written += dataSize;
                    available -= dataSize;
                    const media_status_t mstatus = AMediaCodec_releaseOutputBuffer(
                            codec.get(), status, false /* render */);
                    if (mstatus != AMEDIA_OK) {
                        // AMEDIA_ERROR_UNKNOWN == { -ERANGE -EINVAL -EACCES }
                        ALOGE("%s: AMediaCodec_releaseOutputBuffer"
                                " returned status %d, short decode",
                                __func__, (int)mstatus);
                        break;
                    }
                    if (available == 0) {
                        // there might be more data, but there's no space for it
                        sawOutputEOS = true;
                    }
                } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
                    ALOGV("%s: output buffers changed", __func__);
                } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
                    format.reset(AMediaCodec_getOutputFormat(codec.get())); // update format
                    ALOGV("%s: format changed to: %s",
                           __func__, AMediaFormat_toString(format.get()));
                } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
                    ALOGV("%s: no output buffer right now", __func__);
                } else if (status <= AMEDIA_ERROR_BASE) {
                    ALOGE("%s: decode error: %d", __func__, status);
                    break;
                } else {
                    ALOGV("%s: unexpected info code: %d", __func__, status);
                }
            }

            (void)AMediaCodec_stop(codec.get());
            if (!AMediaFormat_getInt32(
                    format.get(), AMEDIAFORMAT_KEY_SAMPLE_RATE, (int32_t*) rate) ||
                !AMediaFormat_getInt32(
                    format.get(), AMEDIAFORMAT_KEY_CHANNEL_COUNT, channelCount)) {
                return UNKNOWN_ERROR;
            }
            if (!AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_CHANNEL_MASK,
                    (int32_t*) channelMask)) {
                *channelMask = AUDIO_CHANNEL_NONE;
            }
            *sizeInBytes = written;
            return OK;
        }
    }
    return UNKNOWN_ERROR;
}

status_t Sound::doLoad()
{
    ALOGV("%s()", __func__);
    status_t status = NO_INIT;
    if (mFd.get() != -1) {
        mHeap = new MemoryHeapBase(kDefaultHeapSize);

        ALOGV("%s: start decode", __func__);
        uint32_t sampleRate;
        int32_t channelCount;
        audio_format_t format;
        audio_channel_mask_t channelMask;
        status_t status = decode(mFd.get(), mOffset, mLength, &sampleRate, &channelCount, &format,
                        &channelMask, mHeap, &mSizeInBytes);
        ALOGV("%s: close(%d)", __func__, mFd.get());
        mFd.reset();  // close

        if (status != NO_ERROR) {
            ALOGE("%s: unable to load sound", __func__);
        } else if (sampleRate > kMaxSampleRate) {
            ALOGE("%s: sample rate (%u) out of range", __func__, sampleRate);
            status = BAD_VALUE;
        } else if (channelCount < 1 || channelCount > FCC_8) {
            ALOGE("%s: sample channel count (%d) out of range", __func__, channelCount);
            status = BAD_VALUE;
        } else {
            // Correctly loaded, proper parameters
            ALOGV("%s: pointer = %p, sizeInBytes = %zu, sampleRate = %u, channelCount = %d",
                  __func__, mHeap->getBase(), mSizeInBytes, sampleRate, channelCount);
            mData = new MemoryBase(mHeap, 0, mSizeInBytes);
            mSampleRate = sampleRate;
            mChannelCount = channelCount;
            mFormat = format;
            mChannelMask = channelMask;
            mState = READY;  // this should be last, as it is an atomic sync point
            return NO_ERROR;
        }
    } else {
        ALOGE("%s: uninitialized fd, dup failed", __func__);
    }
    // ERROR handling
    mHeap.clear();
    mState = DECODE_ERROR; // this should be last, as it is an atomic sync point
    return status;
}

} // namespace android::soundpool
