/*
 * Copyright (C) 2009 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 "AMRExtractor"
#include <utils/Log.h>

#include <inttypes.h>

#include "AMRExtractor.h"

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <utils/String8.h>

namespace android {

class AMRSource : public MediaTrackHelper {
public:
    AMRSource(
            DataSourceHelper *source,
            AMediaFormat *meta,
            bool isWide,
            const off64_t *offset_table,
            size_t offset_table_length);

    virtual media_status_t start();
    virtual media_status_t stop();

    virtual media_status_t getFormat(AMediaFormat *);

    virtual media_status_t read(
            MediaBufferHelper **buffer, const ReadOptions *options = NULL);

protected:
    virtual ~AMRSource();

private:
    DataSourceHelper *mDataSource;
    AMediaFormat *mMeta;
    bool mIsWide;

    off64_t mOffset;
    int64_t mCurrentTimeUs;
    bool mStarted;
    MediaBufferGroup *mGroup;

    off64_t mOffsetTable[OFFSET_TABLE_LEN];
    size_t mOffsetTableLength;

    AMRSource(const AMRSource &);
    AMRSource &operator=(const AMRSource &);
};

////////////////////////////////////////////////////////////////////////////////

static size_t getFrameSize(bool isWide, unsigned FT) {
    static const size_t kFrameSizeNB[16] = {
        95, 103, 118, 134, 148, 159, 204, 244,
        39, 43, 38, 37, // SID
        0, 0, 0, // future use
        0 // no data
    };
    static const size_t kFrameSizeWB[16] = {
        132, 177, 253, 285, 317, 365, 397, 461, 477,
        40, // SID
        0, 0, 0, 0, // future use
        0, // speech lost
        0 // no data
    };

    if (FT > 15 || (isWide && FT > 9 && FT < 14) || (!isWide && FT > 11 && FT < 15)) {
        ALOGE("illegal AMR frame type %d", FT);
        return 0;
    }

    size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];

    // Round up bits to bytes and add 1 for the header byte.
    frameSize = (frameSize + 7) / 8 + 1;

    return frameSize;
}

static media_status_t getFrameSizeByOffset(DataSourceHelper *source,
        off64_t offset, bool isWide, size_t *frameSize) {
    uint8_t header;
    ssize_t count = source->readAt(offset, &header, 1);
    if (count == 0) {
        return AMEDIA_ERROR_END_OF_STREAM;
    } else if (count < 0) {
        return AMEDIA_ERROR_IO;
    }

    unsigned FT = (header >> 3) & 0x0f;

    *frameSize = getFrameSize(isWide, FT);
    if (*frameSize == 0) {
        return AMEDIA_ERROR_MALFORMED;
    }
    return AMEDIA_OK;
}

static bool SniffAMR(
        DataSourceHelper *source, bool *isWide, float *confidence) {
    char header[9];

    if (source->readAt(0, header, sizeof(header)) != sizeof(header)) {
        return false;
    }

    if (!memcmp(header, "#!AMR\n", 6)) {
        if (isWide != nullptr) {
            *isWide = false;
        }
        *confidence = 0.5;

        return true;
    } else if (!memcmp(header, "#!AMR-WB\n", 9)) {
        if (isWide != nullptr) {
            *isWide = true;
        }
        *confidence = 0.5;

        return true;
    }

    return false;
}

AMRExtractor::AMRExtractor(DataSourceHelper *source)
    : mDataSource(source),
      mMeta(NULL),
      mInitCheck(NO_INIT),
      mOffsetTableLength(0) {
    float confidence;
    if (!SniffAMR(mDataSource, &mIsWide, &confidence)) {
        return;
    }

    mMeta = AMediaFormat_new();
    AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME,
            mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AMR_NB);

    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, 1);
    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, mIsWide ? 16000 : 8000);

    off64_t offset = mIsWide ? 9 : 6;
    off64_t streamSize;
    size_t frameSize, numFrames = 0;
    int64_t duration = 0;

    if (mDataSource->getSize(&streamSize) == OK) {
        while (offset < streamSize) {
            status_t status = getFrameSizeByOffset(source, offset, mIsWide, &frameSize);
            if (status == ERROR_END_OF_STREAM) {
                break;
            } else if (status != OK) {
                return;
            }

            if ((numFrames % 50 == 0) && (numFrames / 50 < OFFSET_TABLE_LEN)) {
                CHECK_EQ(mOffsetTableLength, numFrames / 50);
                mOffsetTable[mOffsetTableLength] = offset - (mIsWide ? 9: 6);
                mOffsetTableLength ++;
            }

            offset += frameSize;
            duration += 20000;  // Each frame is 20ms
            numFrames ++;
        }

        AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_DURATION, duration);
    }

    mInitCheck = OK;
}

AMRExtractor::~AMRExtractor() {
    delete mDataSource;
    if (mMeta) {
        AMediaFormat_delete(mMeta);
    }
}

media_status_t AMRExtractor::getMetaData(AMediaFormat *meta) {
    AMediaFormat_clear(meta);

    if (mInitCheck == OK) {
        AMediaFormat_setString(meta,
                AMEDIAFORMAT_KEY_MIME, mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB : "audio/amr");
    }

    return AMEDIA_OK;
}

size_t AMRExtractor::countTracks() {
    return mInitCheck == OK ? 1 : 0;
}

MediaTrackHelper *AMRExtractor::getTrack(size_t index) {
    if (mInitCheck != OK || index != 0) {
        return NULL;
    }

    return new AMRSource(mDataSource, mMeta, mIsWide,
            mOffsetTable, mOffsetTableLength);
}

media_status_t AMRExtractor::getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t /* flags */) {
    if (mInitCheck != OK || index != 0) {
        return AMEDIA_ERROR_UNKNOWN;
    }

    return AMediaFormat_copy(meta, mMeta);
}

////////////////////////////////////////////////////////////////////////////////

AMRSource::AMRSource(
        DataSourceHelper *source, AMediaFormat *meta,
        bool isWide, const off64_t *offset_table, size_t offset_table_length)
    : mDataSource(source),
      mMeta(meta),
      mIsWide(isWide),
      mOffset(mIsWide ? 9 : 6),
      mCurrentTimeUs(0),
      mStarted(false),
      mGroup(NULL),
      mOffsetTableLength(offset_table_length) {
    if (mOffsetTableLength > 0 && mOffsetTableLength <= OFFSET_TABLE_LEN) {
        memcpy ((char*)mOffsetTable, (char*)offset_table, sizeof(off64_t) * mOffsetTableLength);
    }
}

AMRSource::~AMRSource() {
    if (mStarted) {
        stop();
    }
}

media_status_t AMRSource::start() {
    CHECK(!mStarted);

    mOffset = mIsWide ? 9 : 6;
    mCurrentTimeUs = 0;
    mBufferGroup->add_buffer(128);
    mStarted = true;

    return AMEDIA_OK;
}

media_status_t AMRSource::stop() {
    CHECK(mStarted);

    mStarted = false;
    return AMEDIA_OK;
}

media_status_t AMRSource::getFormat(AMediaFormat *meta) {
    return AMediaFormat_copy(meta, mMeta);
}

media_status_t AMRSource::read(
        MediaBufferHelper **out, const ReadOptions *options) {
    *out = NULL;

    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    if (mOffsetTableLength > 0 && options && options->getSeekTo(&seekTimeUs, &mode)) {
        size_t size;
        const int64_t frameDurationUs = 20000LL;  // 20ms per frame.
        int64_t seekFrame = 0;
        switch(mode & 0x7) {
            case ReadOptions::SEEK_NEXT_SYNC:
                seekFrame = (seekTimeUs + frameDurationUs - 1) / frameDurationUs;
                break;
            case ReadOptions::SEEK_CLOSEST_SYNC:
            case ReadOptions::SEEK_CLOSEST:
                seekFrame = (seekTimeUs + frameDurationUs/2) / frameDurationUs;
                break;
            case ReadOptions::SEEK_PREVIOUS_SYNC:
            default:
                seekFrame = seekTimeUs / frameDurationUs;
                break;
        }
        mCurrentTimeUs = seekFrame * frameDurationUs;

        size_t index = seekFrame < 0 ? 0 : seekFrame / 50;
        if (index >= mOffsetTableLength) {
            index = mOffsetTableLength - 1;
        }

        mOffset = mOffsetTable[index] + (mIsWide ? 9 : 6);

        for (size_t i = 0; i< seekFrame - index * 50; i++) {
            media_status_t err;
            if ((err = getFrameSizeByOffset(mDataSource, mOffset,
                            mIsWide, &size)) != OK) {
                return err;
            }
            mOffset += size;
        }
    }

    uint8_t header;
    ssize_t n = mDataSource->readAt(mOffset, &header, 1);

    if (n < 1) {
        return AMEDIA_ERROR_END_OF_STREAM;
    }

    if (header & 0x83) {
        // Padding bits must be 0.

        ALOGE("padding bits must be 0, header is 0x%02x", header);

        return AMEDIA_ERROR_MALFORMED;
    }

    unsigned FT = (header >> 3) & 0x0f;

    size_t frameSize = getFrameSize(mIsWide, FT);
    if (frameSize == 0) {
        return AMEDIA_ERROR_MALFORMED;
    }

    MediaBufferHelper *buffer;
    status_t err = mBufferGroup->acquire_buffer(&buffer);
    if (err != OK) {
        return AMEDIA_ERROR_UNKNOWN;
    }

    n = mDataSource->readAt(mOffset, buffer->data(), frameSize);

    if (n != (ssize_t)frameSize) {
        buffer->release();
        buffer = NULL;

        if (n < 0) {
            return AMEDIA_ERROR_IO;
        } else {
            // only partial frame is available, treat it as EOS.
            mOffset += n;
            return AMEDIA_ERROR_END_OF_STREAM;
        }
    }

    buffer->set_range(0, frameSize);
    AMediaFormat *meta = buffer->meta_data();
    AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, mCurrentTimeUs);
    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);

    mOffset += frameSize;
    mCurrentTimeUs += 20000;  // Each frame is 20ms

    *out = buffer;

    return AMEDIA_OK;
}

////////////////////////////////////////////////////////////////////////////////

static const char *extensions[] = {
    "amr",
    "awb",
    NULL
};

extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
    return {
        EXTRACTORDEF_VERSION,
        UUID("c86639c9-2f31-40ac-a715-fa01b4493aaf"),
        1,
        "AMR Extractor",
        {
           .v3 = {
               [](
                   CDataSource *source,
                   float *confidence,
                   void **,
                   FreeMetaFunc *) -> CreatorFunc {
                   DataSourceHelper helper(source);
                   if (SniffAMR(&helper, nullptr, confidence)) {
                       return [](
                               CDataSource *source,
                               void *) -> CMediaExtractor* {
                           return wrap(new AMRExtractor(new DataSourceHelper(source)));};
                   }
                   return NULL;
               },
               extensions
           },
        },
    };
}

} // extern "C"

}  // namespace android
