/*
 * Copyright (C) 2011 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.
 */

#include <fcntl.h>
#include <inttypes.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>

//#define LOG_NDEBUG 0
#define LOG_TAG "AACWriter"
#include <utils/Log.h>

#include <media/openmax/OMX_Audio.h>
#include <media/stagefright/AACWriter.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/mediarecorder.h>

namespace android {

AACWriter::AACWriter(int fd)
    : mFd(dup(fd)),
      mInitCheck(mFd < 0? NO_INIT: OK),
      mStarted(false),
      mPaused(false),
      mResumed(false),
      mThread(0),
      mEstimatedSizeBytes(0),
      mEstimatedDurationUs(0),
      mChannelCount(-1),
      mSampleRate(-1),
      mAACProfile(OMX_AUDIO_AACObjectLC),
      mFrameDurationUs(0) {
}

AACWriter::~AACWriter() {
    if (mStarted) {
        reset();
    }

    if (mFd != -1) {
        close(mFd);
        mFd = -1;
    }
}

status_t AACWriter::initCheck() const {
    return mInitCheck;
}


status_t AACWriter::addSource(const sp<MediaSource> &source) {
    if (mInitCheck != OK) {
        return mInitCheck;
    }

    if (mSource != NULL) {
        ALOGE("AAC files only support a single track of audio.");
        return UNKNOWN_ERROR;
    }

    sp<MetaData> meta = source->getFormat();

    const char *mime;
    CHECK(meta->findCString(kKeyMIMEType, &mime));

    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC));
    CHECK(meta->findInt32(kKeyChannelCount, &mChannelCount));
    CHECK(meta->findInt32(kKeySampleRate, &mSampleRate));
    CHECK(mChannelCount >= 1 && mChannelCount <= 2);

    // Optionally, we want to check whether AACProfile is also set.
    if (meta->findInt32(kKeyAACProfile, &mAACProfile)) {
        ALOGI("AAC profile is changed to %d", mAACProfile);
    }

    mSource = source;
    return OK;
}

status_t AACWriter::start(MetaData * /* params */) {
    if (mInitCheck != OK) {
        return mInitCheck;
    }

    if (mSource == NULL) {
        return UNKNOWN_ERROR;
    }

    if (mStarted && mPaused) {
        mPaused = false;
        mResumed = true;
        return OK;
    } else if (mStarted) {
        // Already started, does nothing
        return OK;
    }

    mFrameDurationUs = (kSamplesPerFrame * 1000000LL + (mSampleRate >> 1))
                            / mSampleRate;

    status_t err = mSource->start();

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

    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    mReachedEOS = false;
    mDone = false;

    pthread_create(&mThread, &attr, ThreadWrapper, this);
    pthread_attr_destroy(&attr);

    mStarted = true;

    return OK;
}

status_t AACWriter::pause() {
    if (!mStarted) {
        return OK;
    }
    mPaused = true;
    return OK;
}

status_t AACWriter::reset() {
    if (!mStarted) {
        return OK;
    }

    mDone = true;

    void *dummy;
    pthread_join(mThread, &dummy);

    status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
    {
        status_t status = mSource->stop();
        if (err == OK &&
            (status != OK && status != ERROR_END_OF_STREAM)) {
            err = status;
        }
    }

    mStarted = false;
    return err;
}

bool AACWriter::exceedsFileSizeLimit() {
    if (mMaxFileSizeLimitBytes == 0) {
        return false;
    }
    return mEstimatedSizeBytes >= mMaxFileSizeLimitBytes;
}

bool AACWriter::exceedsFileDurationLimit() {
    if (mMaxFileDurationLimitUs == 0) {
        return false;
    }
    return mEstimatedDurationUs >= mMaxFileDurationLimitUs;
}

// static
void *AACWriter::ThreadWrapper(void *me) {
    return (void *)(uintptr_t)static_cast<AACWriter *>(me)->threadFunc();
}

/*
* Returns an index into the sample rate table if the
* given sample rate is found; otherwise, returns -1.
*/
static bool getSampleRateTableIndex(int sampleRate, uint8_t* tableIndex) {
    static const int kSampleRateTable[] = {
        96000, 88200, 64000, 48000, 44100, 32000,
        24000, 22050, 16000, 12000, 11025, 8000
    };
    const int tableSize =
        sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);

    *tableIndex = 0;
    for (int index = 0; index < tableSize; ++index) {
        if (sampleRate == kSampleRateTable[index]) {
            ALOGV("Sample rate: %d and index: %d",
                sampleRate, index);
            *tableIndex = index;
            return true;
        }
    }

    ALOGE("Sampling rate %d bps is not supported", sampleRate);
    return false;
}

/*
 * ADTS (Audio data transport stream) header structure.
 * It consists of 7 or 9 bytes (with or without CRC):
 * 12 bits of syncword 0xFFF, all bits must be 1
 * 1 bit of field ID. 0 for MPEG-4, and 1 for MPEG-2
 * 2 bits of MPEG layer. If in MPEG-TS, set to 0
 * 1 bit of protection absense. Set to 1 if no CRC.
 * 2 bits of profile code. Set to 1 (The MPEG-4 Audio
 *   object type minus 1. We are using AAC-LC = 2)
 * 4 bits of sampling frequency index code (15 is not allowed)
 * 1 bit of private stream. Set to 0.
 * 3 bits of channel configuration code. 0 resevered for inband PCM
 * 1 bit of originality. Set to 0.
 * 1 bit of home. Set to 0.
 * 1 bit of copyrighted steam. Set to 0.
 * 1 bit of copyright start. Set to 0.
 * 13 bits of frame length. It included 7 ot 9 bytes header length.
 *   it is set to (protection absense? 7: 9) + size(AAC frame)
 * 11 bits of buffer fullness. 0x7FF for VBR.
 * 2 bits of frames count in one packet. Set to 0.
 */
status_t AACWriter::writeAdtsHeader(uint32_t frameLength) {
    uint8_t data = 0xFF;
    write(mFd, &data, 1);

    const uint8_t kFieldId = 0;
    const uint8_t kMpegLayer = 0;
    const uint8_t kProtectionAbsense = 1;  // 1: kAdtsHeaderLength = 7
    data = 0xF0;
    data |= (kFieldId << 3);
    data |= (kMpegLayer << 1);
    data |= kProtectionAbsense;
    write(mFd, &data, 1);

    const uint8_t kProfileCode = mAACProfile - 1;
    uint8_t kSampleFreqIndex;
    CHECK(getSampleRateTableIndex(mSampleRate, &kSampleFreqIndex));
    const uint8_t kPrivateStream = 0;
    const uint8_t kChannelConfigCode = mChannelCount;
    data = (kProfileCode << 6);
    data |= (kSampleFreqIndex << 2);
    data |= (kPrivateStream << 1);
    data |= (kChannelConfigCode >> 2);
    write(mFd, &data, 1);

    // 4 bits from originality to copyright start
    const uint8_t kCopyright = 0;
    const uint32_t kFrameLength = frameLength;
    data = ((kChannelConfigCode & 3) << 6);
    data |= (kCopyright << 2);
    data |= ((kFrameLength & 0x1800) >> 11);
    write(mFd, &data, 1);

    data = ((kFrameLength & 0x07F8) >> 3);
    write(mFd, &data, 1);

    const uint32_t kBufferFullness = 0x7FF;  // VBR
    data = ((kFrameLength & 0x07) << 5);
    data |= ((kBufferFullness & 0x07C0) >> 6);
    write(mFd, &data, 1);

    const uint8_t kFrameCount = 0;
    data = ((kBufferFullness & 0x03F) << 2);
    data |= kFrameCount;
    write(mFd, &data, 1);

    return OK;
}

status_t AACWriter::threadFunc() {
    mEstimatedDurationUs = 0;
    mEstimatedSizeBytes = 0;
    int64_t previousPausedDurationUs = 0;
    int64_t maxTimestampUs = 0;
    status_t err = OK;
    bool stoppedPrematurely = true;

    prctl(PR_SET_NAME, (unsigned long)"AACWriterThread", 0, 0, 0);

    while (!mDone && err == OK) {
        MediaBuffer *buffer;
        err = mSource->read(&buffer);

        if (err != OK) {
            break;
        }

        if (mPaused) {
            buffer->release();
            buffer = NULL;
            continue;
        }

        mEstimatedSizeBytes += kAdtsHeaderLength + buffer->range_length();
        if (exceedsFileSizeLimit()) {
            buffer->release();
            buffer = NULL;
            notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
            break;
        }

        int32_t isCodecSpecific = 0;
        if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecSpecific) && isCodecSpecific) {
            ALOGV("Drop codec specific info buffer");
            buffer->release();
            buffer = NULL;
            continue;
        }

        int64_t timestampUs;
        CHECK(buffer->meta_data()->findInt64(kKeyTime, &timestampUs));
        if (timestampUs > mEstimatedDurationUs) {
            mEstimatedDurationUs = timestampUs;
        }
        if (mResumed) {
            previousPausedDurationUs += (timestampUs - maxTimestampUs - mFrameDurationUs);
            mResumed = false;
        }
        timestampUs -= previousPausedDurationUs;
        ALOGV("time stamp: %" PRId64 ", previous paused duration: %" PRId64,
            timestampUs, previousPausedDurationUs);
        if (timestampUs > maxTimestampUs) {
            maxTimestampUs = timestampUs;
        }

        if (exceedsFileDurationLimit()) {
            buffer->release();
            buffer = NULL;
            notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
            break;
        }

        // Each output AAC audio frame to the file contains
        // 1. an ADTS header, followed by
        // 2. the compressed audio data.
        ssize_t dataLength = buffer->range_length();
        uint8_t *data = (uint8_t *)buffer->data() + buffer->range_offset();
        if (writeAdtsHeader(kAdtsHeaderLength + dataLength) != OK ||
            dataLength != write(mFd, data, dataLength)) {
            err = ERROR_IO;
        }

        buffer->release();
        buffer = NULL;

        if (err != OK) {
            break;
        }

        if (stoppedPrematurely) {
            stoppedPrematurely = false;
        }
    }

    if ((err == OK || err == ERROR_END_OF_STREAM) && stoppedPrematurely) {
        err = ERROR_MALFORMED;
    }

    close(mFd);
    mFd = -1;
    mReachedEOS = true;
    if (err == ERROR_END_OF_STREAM) {
        return OK;
    }
    return err;
}

bool AACWriter::reachedEOS() {
    return mReachedEOS;
}

}  // namespace android
