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

#include "SimplePlayer.h"

#include <gui/Surface.h>
#include <media/AudioTrack.h>
#include <media/ICrypto.h>
#include <media/IMediaHTTPService.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/NativeWindowWrapper.h>
#include <media/stagefright/NuMediaExtractor.h>

namespace android {

SimplePlayer::SimplePlayer()
    : mState(UNINITIALIZED),
      mDoMoreStuffGeneration(0),
      mStartTimeRealUs(-1ll) {
}

SimplePlayer::~SimplePlayer() {
}

// static
status_t PostAndAwaitResponse(
        const sp<AMessage> &msg, sp<AMessage> *response) {
    status_t err = msg->postAndAwaitResponse(response);

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

    if (!(*response)->findInt32("err", &err)) {
        err = OK;
    }

    return err;
}
status_t SimplePlayer::setDataSource(const char *path) {
    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
    msg->setString("path", path);
    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}

status_t SimplePlayer::setSurface(const sp<IGraphicBufferProducer> &bufferProducer) {
    sp<AMessage> msg = new AMessage(kWhatSetSurface, id());

    sp<Surface> surface;
    if (bufferProducer != NULL) {
        surface = new Surface(bufferProducer);
    }

    msg->setObject(
            "native-window", new NativeWindowWrapper(surface));

    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}

status_t SimplePlayer::prepare() {
    sp<AMessage> msg = new AMessage(kWhatPrepare, id());
    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}

status_t SimplePlayer::start() {
    sp<AMessage> msg = new AMessage(kWhatStart, id());
    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}

status_t SimplePlayer::stop() {
    sp<AMessage> msg = new AMessage(kWhatStop, id());
    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}

status_t SimplePlayer::reset() {
    sp<AMessage> msg = new AMessage(kWhatReset, id());
    sp<AMessage> response;
    return PostAndAwaitResponse(msg, &response);
}

void SimplePlayer::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatSetDataSource:
        {
            status_t err;
            if (mState != UNINITIALIZED) {
                err = INVALID_OPERATION;
            } else {
                CHECK(msg->findString("path", &mPath));
                mState = UNPREPARED;
            }

            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatSetSurface:
        {
            status_t err;
            if (mState != UNPREPARED) {
                err = INVALID_OPERATION;
            } else {
                sp<RefBase> obj;
                CHECK(msg->findObject("native-window", &obj));

                mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());

                err = OK;
            }

            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatPrepare:
        {
            status_t err;
            if (mState != UNPREPARED) {
                err = INVALID_OPERATION;
            } else {
                err = onPrepare();

                if (err == OK) {
                    mState = STOPPED;
                }
            }

            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatStart:
        {
            status_t err = OK;

            if (mState == UNPREPARED) {
                err = onPrepare();

                if (err == OK) {
                    mState = STOPPED;
                }
            }

            if (err == OK) {
                if (mState != STOPPED) {
                    err = INVALID_OPERATION;
                } else {
                    err = onStart();

                    if (err == OK) {
                        mState = STARTED;
                    }
                }
            }

            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatStop:
        {
            status_t err;

            if (mState != STARTED) {
                err = INVALID_OPERATION;
            } else {
                err = onStop();

                if (err == OK) {
                    mState = STOPPED;
                }
            }

            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatReset:
        {
            status_t err = OK;

            if (mState == STARTED) {
                CHECK_EQ(onStop(), (status_t)OK);
                mState = STOPPED;
            }

            if (mState == STOPPED) {
                err = onReset();
                mState = UNINITIALIZED;
            }

            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatDoMoreStuff:
        {
            int32_t generation;
            CHECK(msg->findInt32("generation", &generation));

            if (generation != mDoMoreStuffGeneration) {
                break;
            }

            status_t err = onDoMoreStuff();

            if (err == OK) {
                msg->post(10000ll);
            }
            break;
        }

        default:
            TRESPASS();
    }
}

status_t SimplePlayer::onPrepare() {
    CHECK_EQ(mState, UNPREPARED);

    mExtractor = new NuMediaExtractor;

    status_t err = mExtractor->setDataSource(
            NULL /* httpService */, mPath.c_str());

    if (err != OK) {
        mExtractor.clear();
        return err;
    }

    if (mCodecLooper == NULL) {
        mCodecLooper = new ALooper;
        mCodecLooper->start();
    }

    bool haveAudio = false;
    bool haveVideo = false;
    for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
        sp<AMessage> format;
        status_t err = mExtractor->getTrackFormat(i, &format);
        CHECK_EQ(err, (status_t)OK);

        AString mime;
        CHECK(format->findString("mime", &mime));

        bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);

        if (!haveAudio && !strncasecmp(mime.c_str(), "audio/", 6)) {
            haveAudio = true;
        } else if (!haveVideo && isVideo) {
            haveVideo = true;
        } else {
            continue;
        }

        err = mExtractor->selectTrack(i);
        CHECK_EQ(err, (status_t)OK);

        CodecState *state =
            &mStateByTrackIndex.editValueAt(
                    mStateByTrackIndex.add(i, CodecState()));

        state->mNumFramesWritten = 0;
        state->mCodec = MediaCodec::CreateByType(
                mCodecLooper, mime.c_str(), false /* encoder */);

        CHECK(state->mCodec != NULL);

        err = state->mCodec->configure(
                format,
                isVideo ? mNativeWindow->getSurfaceTextureClient() : NULL,
                NULL /* crypto */,
                0 /* flags */);

        CHECK_EQ(err, (status_t)OK);

        size_t j = 0;
        sp<ABuffer> buffer;
        while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) {
            state->mCSD.push_back(buffer);

            ++j;
        }
    }

    for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
        CodecState *state = &mStateByTrackIndex.editValueAt(i);

        status_t err = state->mCodec->start();
        CHECK_EQ(err, (status_t)OK);

        err = state->mCodec->getInputBuffers(&state->mBuffers[0]);
        CHECK_EQ(err, (status_t)OK);

        err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
        CHECK_EQ(err, (status_t)OK);

        for (size_t j = 0; j < state->mCSD.size(); ++j) {
            const sp<ABuffer> &srcBuffer = state->mCSD.itemAt(j);

            size_t index;
            err = state->mCodec->dequeueInputBuffer(&index, -1ll);
            CHECK_EQ(err, (status_t)OK);

            const sp<ABuffer> &dstBuffer = state->mBuffers[0].itemAt(index);

            CHECK_LE(srcBuffer->size(), dstBuffer->capacity());
            dstBuffer->setRange(0, srcBuffer->size());
            memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size());

            err = state->mCodec->queueInputBuffer(
                    index,
                    0,
                    dstBuffer->size(),
                    0ll,
                    MediaCodec::BUFFER_FLAG_CODECCONFIG);
            CHECK_EQ(err, (status_t)OK);
        }
    }

    return OK;
}

status_t SimplePlayer::onStart() {
    CHECK_EQ(mState, STOPPED);

    mStartTimeRealUs = -1ll;

    sp<AMessage> msg = new AMessage(kWhatDoMoreStuff, id());
    msg->setInt32("generation", ++mDoMoreStuffGeneration);
    msg->post();

    return OK;
}

status_t SimplePlayer::onStop() {
    CHECK_EQ(mState, STARTED);

    ++mDoMoreStuffGeneration;

    return OK;
}

status_t SimplePlayer::onReset() {
    CHECK_EQ(mState, STOPPED);

    for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
        CodecState *state = &mStateByTrackIndex.editValueAt(i);

        CHECK_EQ(state->mCodec->release(), (status_t)OK);
    }

    mStartTimeRealUs = -1ll;

    mStateByTrackIndex.clear();
    mCodecLooper.clear();
    mExtractor.clear();
    mNativeWindow.clear();
    mPath.clear();

    return OK;
}

status_t SimplePlayer::onDoMoreStuff() {
    ALOGV("onDoMoreStuff");
    for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
        CodecState *state = &mStateByTrackIndex.editValueAt(i);

        status_t err;
        do {
            size_t index;
            err = state->mCodec->dequeueInputBuffer(&index);

            if (err == OK) {
                ALOGV("dequeued input buffer on track %d",
                      mStateByTrackIndex.keyAt(i));

                state->mAvailInputBufferIndices.push_back(index);
            } else {
                ALOGV("dequeueInputBuffer on track %d returned %d",
                      mStateByTrackIndex.keyAt(i), err);
            }
        } while (err == OK);

        do {
            BufferInfo info;
            err = state->mCodec->dequeueOutputBuffer(
                    &info.mIndex,
                    &info.mOffset,
                    &info.mSize,
                    &info.mPresentationTimeUs,
                    &info.mFlags);

            if (err == OK) {
                ALOGV("dequeued output buffer on track %d",
                      mStateByTrackIndex.keyAt(i));

                state->mAvailOutputBufferInfos.push_back(info);
            } else if (err == INFO_FORMAT_CHANGED) {
                err = onOutputFormatChanged(mStateByTrackIndex.keyAt(i), state);
                CHECK_EQ(err, (status_t)OK);
            } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
                err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
                CHECK_EQ(err, (status_t)OK);
            } else {
                ALOGV("dequeueOutputBuffer on track %d returned %d",
                      mStateByTrackIndex.keyAt(i), err);
            }
        } while (err == OK
                || err == INFO_FORMAT_CHANGED
                || err == INFO_OUTPUT_BUFFERS_CHANGED);
    }

    for (;;) {
        size_t trackIndex;
        status_t err = mExtractor->getSampleTrackIndex(&trackIndex);

        if (err != OK) {
            ALOGI("encountered input EOS.");
            break;
        } else {
            CodecState *state = &mStateByTrackIndex.editValueFor(trackIndex);

            if (state->mAvailInputBufferIndices.empty()) {
                break;
            }

            size_t index = *state->mAvailInputBufferIndices.begin();
            state->mAvailInputBufferIndices.erase(
                    state->mAvailInputBufferIndices.begin());

            const sp<ABuffer> &dstBuffer =
                state->mBuffers[0].itemAt(index);

            err = mExtractor->readSampleData(dstBuffer);
            CHECK_EQ(err, (status_t)OK);

            int64_t timeUs;
            CHECK_EQ(mExtractor->getSampleTime(&timeUs), (status_t)OK);

            err = state->mCodec->queueInputBuffer(
                    index,
                    dstBuffer->offset(),
                    dstBuffer->size(),
                    timeUs,
                    0);
            CHECK_EQ(err, (status_t)OK);

            ALOGV("enqueued input data on track %d", trackIndex);

            err = mExtractor->advance();
            CHECK_EQ(err, (status_t)OK);
        }
    }

    int64_t nowUs = ALooper::GetNowUs();

    if (mStartTimeRealUs < 0ll) {
        mStartTimeRealUs = nowUs + 1000000ll;
    }

    for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
        CodecState *state = &mStateByTrackIndex.editValueAt(i);

        while (!state->mAvailOutputBufferInfos.empty()) {
            BufferInfo *info = &*state->mAvailOutputBufferInfos.begin();

            int64_t whenRealUs = info->mPresentationTimeUs + mStartTimeRealUs;
            int64_t lateByUs = nowUs - whenRealUs;

            if (lateByUs > -10000ll) {
                bool release = true;

                if (lateByUs > 30000ll) {
                    ALOGI("track %d buffer late by %lld us, dropping.",
                          mStateByTrackIndex.keyAt(i), lateByUs);
                    state->mCodec->releaseOutputBuffer(info->mIndex);
                } else {
                    if (state->mAudioTrack != NULL) {
                        const sp<ABuffer> &srcBuffer =
                            state->mBuffers[1].itemAt(info->mIndex);

                        renderAudio(state, info, srcBuffer);

                        if (info->mSize > 0) {
                            release = false;
                        }
                    }

                    if (release) {
                        state->mCodec->renderOutputBufferAndRelease(
                                info->mIndex);
                    }
                }

                if (release) {
                    state->mAvailOutputBufferInfos.erase(
                            state->mAvailOutputBufferInfos.begin());

                    info = NULL;
                } else {
                    break;
                }
            } else {
                ALOGV("track %d buffer early by %lld us.",
                      mStateByTrackIndex.keyAt(i), -lateByUs);
                break;
            }
        }
    }

    return OK;
}

status_t SimplePlayer::onOutputFormatChanged(
        size_t trackIndex, CodecState *state) {
    sp<AMessage> format;
    status_t err = state->mCodec->getOutputFormat(&format);

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

    AString mime;
    CHECK(format->findString("mime", &mime));

    if (!strncasecmp(mime.c_str(), "audio/", 6)) {
        int32_t channelCount;
        int32_t sampleRate;
        CHECK(format->findInt32("channel-count", &channelCount));
        CHECK(format->findInt32("sample-rate", &sampleRate));

        state->mAudioTrack = new AudioTrack(
                AUDIO_STREAM_MUSIC,
                sampleRate,
                AUDIO_FORMAT_PCM_16_BIT,
                audio_channel_out_mask_from_count(channelCount),
                0);

        state->mNumFramesWritten = 0;
    }

    return OK;
}

void SimplePlayer::renderAudio(
        CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer) {
    CHECK(state->mAudioTrack != NULL);

    if (state->mAudioTrack->stopped()) {
        state->mAudioTrack->start();
    }

    uint32_t numFramesPlayed;
    CHECK_EQ(state->mAudioTrack->getPosition(&numFramesPlayed), (status_t)OK);

    uint32_t numFramesAvailableToWrite =
        state->mAudioTrack->frameCount()
            - (state->mNumFramesWritten - numFramesPlayed);

    size_t numBytesAvailableToWrite =
        numFramesAvailableToWrite * state->mAudioTrack->frameSize();

    size_t copy = info->mSize;
    if (copy > numBytesAvailableToWrite) {
        copy = numBytesAvailableToWrite;
    }

    if (copy == 0) {
        return;
    }

    int64_t startTimeUs = ALooper::GetNowUs();

    ssize_t nbytes = state->mAudioTrack->write(
            buffer->base() + info->mOffset, copy);

    CHECK_EQ(nbytes, (ssize_t)copy);

    int64_t delayUs = ALooper::GetNowUs() - startTimeUs;

    uint32_t numFramesWritten = nbytes / state->mAudioTrack->frameSize();

    if (delayUs > 2000ll) {
        ALOGW("AudioTrack::write took %lld us, numFramesAvailableToWrite=%u, "
              "numFramesWritten=%u",
              delayUs, numFramesAvailableToWrite, numFramesWritten);
    }

    info->mOffset += nbytes;
    info->mSize -= nbytes;

    state->mNumFramesWritten += numFramesWritten;
}

}  // namespace android
