/*
 * 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.
 */

#define LOG_NDEBUG 1
#define LOG_TAG "VideoEditorPlayer"
#include <utils/Log.h>

#include "VideoEditorPlayer.h"
#include "PreviewPlayer.h"

#include <media/Metadata.h>
#include <media/stagefright/MediaExtractor.h>

#include <system/audio.h>

namespace android {

VideoEditorPlayer::VideoEditorPlayer(NativeWindowRenderer* renderer)
    : mPlayer(new PreviewPlayer(renderer)) {

    ALOGV("VideoEditorPlayer");
    mPlayer->setListener(this);
}

VideoEditorPlayer::~VideoEditorPlayer() {
    ALOGV("~VideoEditorPlayer");

    reset();
    mVeAudioSink.clear();

    delete mPlayer;
    mPlayer = NULL;
}

status_t VideoEditorPlayer::initCheck() {
    ALOGV("initCheck");
    return OK;
}


status_t VideoEditorPlayer::setAudioPlayer(VideoEditorAudioPlayer *audioPlayer) {
    return mPlayer->setAudioPlayer(audioPlayer);
}


status_t VideoEditorPlayer::setDataSource(
        const char *url, const KeyedVector<String8, String8> *headers) {
    ALOGI("setDataSource('%s')", url);
    if (headers != NULL) {
        ALOGE("Headers parameter is not supported");
        return INVALID_OPERATION;
    }

    return mPlayer->setDataSource(url);
}

//We donot use this in preview, dummy implimentation as this is pure virtual
status_t VideoEditorPlayer::setDataSource(int fd, int64_t offset,
    int64_t length) {
    ALOGE("setDataSource(%d, %lld, %lld) Not supported", fd, offset, length);
    return (!OK);
}

status_t VideoEditorPlayer::setVideoSurface(const sp<Surface> &surface) {
    ALOGV("setVideoSurface");

    mPlayer->setSurface(surface);
    return OK;
}

status_t VideoEditorPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
    ALOGV("setVideoSurfaceTexture");

    mPlayer->setSurfaceTexture(surfaceTexture);
    return OK;
}

status_t VideoEditorPlayer::prepare() {
    ALOGV("prepare");
    return mPlayer->prepare();
}

status_t VideoEditorPlayer::prepareAsync() {
    return mPlayer->prepareAsync();
}

status_t VideoEditorPlayer::start() {
    ALOGV("start");
    return mPlayer->play();
}

status_t VideoEditorPlayer::stop() {
    ALOGV("stop");
    return pause();
}

status_t VideoEditorPlayer::pause() {
    ALOGV("pause");
    return mPlayer->pause();
}

bool VideoEditorPlayer::isPlaying() {
    ALOGV("isPlaying");
    return mPlayer->isPlaying();
}

status_t VideoEditorPlayer::seekTo(int msec) {
    ALOGV("seekTo");
    status_t err = mPlayer->seekTo((int64_t)msec * 1000);
    return err;
}

status_t VideoEditorPlayer::getCurrentPosition(int *msec) {
    ALOGV("getCurrentPosition");
    int64_t positionUs;
    status_t err = mPlayer->getPosition(&positionUs);

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

    *msec = (positionUs + 500) / 1000;
    return OK;
}

status_t VideoEditorPlayer::getDuration(int *msec) {
    ALOGV("getDuration");

    int64_t durationUs;
    status_t err = mPlayer->getDuration(&durationUs);

    if (err != OK) {
        *msec = 0;
        return OK;
    }

    *msec = (durationUs + 500) / 1000;
    return OK;
}

status_t VideoEditorPlayer::reset() {
    ALOGV("reset");
    mPlayer->reset();
    return OK;
}

status_t VideoEditorPlayer::setLooping(int loop) {
    ALOGV("setLooping");
    return mPlayer->setLooping(loop);
}

status_t VideoEditorPlayer::setParameter(int key, const Parcel &request) {
    ALOGE("setParameter not implemented");
    return INVALID_OPERATION;
}

status_t VideoEditorPlayer::getParameter(int key, Parcel *reply) {
    ALOGE("getParameter not implemented");
    return INVALID_OPERATION;
}

player_type VideoEditorPlayer::playerType() {
    ALOGV("playerType");
    return STAGEFRIGHT_PLAYER;
}

void VideoEditorPlayer::acquireLock() {
    ALOGV("acquireLock");
    mPlayer->acquireLock();
}

void VideoEditorPlayer::releaseLock() {
    ALOGV("releaseLock");
    mPlayer->releaseLock();
}

status_t VideoEditorPlayer::invoke(const Parcel &request, Parcel *reply) {
    return INVALID_OPERATION;
}

void VideoEditorPlayer::setAudioSink(const sp<AudioSink> &audioSink) {
    MediaPlayerInterface::setAudioSink(audioSink);

    mPlayer->setAudioSink(audioSink);
}

status_t VideoEditorPlayer::getMetadata(
        const media::Metadata::Filter& ids, Parcel *records) {
    using media::Metadata;

    uint32_t flags = mPlayer->getSourceSeekFlags();

    Metadata metadata(records);

    metadata.appendBool(
            Metadata::kPauseAvailable,
            flags & MediaExtractor::CAN_PAUSE);

    metadata.appendBool(
            Metadata::kSeekBackwardAvailable,
            flags & MediaExtractor::CAN_SEEK_BACKWARD);

    metadata.appendBool(
            Metadata::kSeekForwardAvailable,
            flags & MediaExtractor::CAN_SEEK_FORWARD);

    metadata.appendBool(
            Metadata::kSeekAvailable,
            flags & MediaExtractor::CAN_SEEK);

    return OK;
}

status_t VideoEditorPlayer::loadEffectsSettings(
    M4VSS3GPP_EffectSettings* pEffectSettings, int nEffects) {
    ALOGV("loadEffectsSettings");
    return mPlayer->loadEffectsSettings(pEffectSettings, nEffects);
}

status_t VideoEditorPlayer::loadAudioMixSettings(
    M4xVSS_AudioMixingSettings* pAudioMixSettings) {
    ALOGV("VideoEditorPlayer: loadAudioMixSettings");
    return mPlayer->loadAudioMixSettings(pAudioMixSettings);
}

status_t VideoEditorPlayer::setAudioMixPCMFileHandle(
    M4OSA_Context pAudioMixPCMFileHandle) {

    ALOGV("VideoEditorPlayer: loadAudioMixSettings");
    return mPlayer->setAudioMixPCMFileHandle(pAudioMixPCMFileHandle);
}

status_t VideoEditorPlayer::setAudioMixStoryBoardParam(
    M4OSA_UInt32 audioMixStoryBoardTS,
    M4OSA_UInt32 currentMediaBeginCutTime,
    M4OSA_UInt32 primaryTrackVolValue) {

    ALOGV("VideoEditorPlayer: loadAudioMixSettings");
    return mPlayer->setAudioMixStoryBoardParam(audioMixStoryBoardTS,
     currentMediaBeginCutTime, primaryTrackVolValue);
}

status_t VideoEditorPlayer::setPlaybackBeginTime(uint32_t msec) {
    ALOGV("setPlaybackBeginTime");
    return mPlayer->setPlaybackBeginTime(msec);
}

status_t VideoEditorPlayer::setPlaybackEndTime(uint32_t msec) {
    ALOGV("setPlaybackEndTime");
    return mPlayer->setPlaybackEndTime(msec);
}

status_t VideoEditorPlayer::setStoryboardStartTime(uint32_t msec) {
    ALOGV("setStoryboardStartTime");
    return mPlayer->setStoryboardStartTime(msec);
}

status_t VideoEditorPlayer::setProgressCallbackInterval(uint32_t cbInterval) {
    ALOGV("setProgressCallbackInterval");
    return mPlayer->setProgressCallbackInterval(cbInterval);
}

status_t VideoEditorPlayer::setMediaRenderingMode(
    M4xVSS_MediaRendering mode,
    M4VIDEOEDITING_VideoFrameSize outputVideoSize) {

    ALOGV("setMediaRenderingMode");
    return mPlayer->setMediaRenderingMode(mode, outputVideoSize);
}

status_t VideoEditorPlayer::resetJniCallbackTimeStamp() {
    ALOGV("resetJniCallbackTimeStamp");
    return mPlayer->resetJniCallbackTimeStamp();
}

status_t VideoEditorPlayer::setImageClipProperties(
    uint32_t width, uint32_t height) {
    return mPlayer->setImageClipProperties(width, height);
}

status_t VideoEditorPlayer::readFirstVideoFrame() {
    return mPlayer->readFirstVideoFrame();
}

status_t VideoEditorPlayer::getLastRenderedTimeMs(uint32_t *lastRenderedTimeMs) {
    mPlayer->getLastRenderedTimeMs(lastRenderedTimeMs);
    return NO_ERROR;
}

/* Implementation of AudioSink interface */
#undef LOG_TAG
#define LOG_TAG "VeAudioSink"

int VideoEditorPlayer::VeAudioOutput::mMinBufferCount = 4;
bool VideoEditorPlayer::VeAudioOutput::mIsOnEmulator = false;

VideoEditorPlayer::VeAudioOutput::VeAudioOutput()
    : mCallback(NULL),
      mCallbackCookie(NULL) {
    mTrack = 0;
    mStreamType = AUDIO_STREAM_MUSIC;
    mLeftVolume = 1.0;
    mRightVolume = 1.0;
    mLatency = 0;
    mMsecsPerFrame = 0;
    mNumFramesWritten = 0;
    setMinBufferCount();
}

VideoEditorPlayer::VeAudioOutput::~VeAudioOutput() {
    close();
}

void VideoEditorPlayer::VeAudioOutput::setMinBufferCount() {

    mIsOnEmulator = false;
    mMinBufferCount = 4;
}

bool VideoEditorPlayer::VeAudioOutput::isOnEmulator() {

    setMinBufferCount();
    return mIsOnEmulator;
}

int VideoEditorPlayer::VeAudioOutput::getMinBufferCount() {

    setMinBufferCount();
    return mMinBufferCount;
}

ssize_t VideoEditorPlayer::VeAudioOutput::bufferSize() const {

    if (mTrack == 0) return NO_INIT;
    return mTrack->frameCount() * frameSize();
}

ssize_t VideoEditorPlayer::VeAudioOutput::frameCount() const {

    if (mTrack == 0) return NO_INIT;
    return mTrack->frameCount();
}

ssize_t VideoEditorPlayer::VeAudioOutput::channelCount() const
{
    if (mTrack == 0) return NO_INIT;
    return mTrack->channelCount();
}

ssize_t VideoEditorPlayer::VeAudioOutput::frameSize() const
{
    if (mTrack == 0) return NO_INIT;
    return mTrack->frameSize();
}

uint32_t VideoEditorPlayer::VeAudioOutput::latency () const
{
    return mLatency;
}

float VideoEditorPlayer::VeAudioOutput::msecsPerFrame() const
{
    return mMsecsPerFrame;
}

status_t VideoEditorPlayer::VeAudioOutput::getPosition(uint32_t *position) const {

    if (mTrack == 0) return NO_INIT;
    return mTrack->getPosition(position);
}

status_t VideoEditorPlayer::VeAudioOutput::getFramesWritten(uint32_t *written) const {

    if (mTrack == 0) return NO_INIT;
    *written = mNumFramesWritten;
    return OK;
}

status_t VideoEditorPlayer::VeAudioOutput::open(
        uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
        audio_format_t format, int bufferCount,
        AudioCallback cb, void *cookie, audio_output_flags_t flags) {

    mCallback = cb;
    mCallbackCookie = cookie;

    // Check argument "bufferCount" against the mininum buffer count
    if (bufferCount < mMinBufferCount) {
        ALOGV("bufferCount (%d) is too small and increased to %d",
            bufferCount, mMinBufferCount);
        bufferCount = mMinBufferCount;

    }
    ALOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
    if (mTrack) close();
    int afSampleRate;
    int afFrameCount;
    int frameCount;

    if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) !=
     NO_ERROR) {
        return NO_INIT;
    }
    if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) !=
     NO_ERROR) {
        return NO_INIT;
    }

    frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;

    if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
        switch(channelCount) {
          case 1:
            channelMask = AUDIO_CHANNEL_OUT_MONO;
            break;
          case 2:
            channelMask = AUDIO_CHANNEL_OUT_STEREO;
            break;
          default:
            return NO_INIT;
        }
    }

    AudioTrack *t;
    if (mCallback != NULL) {
        t = new AudioTrack(
                mStreamType,
                sampleRate,
                format,
                channelMask,
                frameCount,
                flags,
                CallbackWrapper,
                this);
    } else {
        t = new AudioTrack(
                mStreamType,
                sampleRate,
                format,
                channelMask,
                frameCount,
                flags);
    }

    if ((t == 0) || (t->initCheck() != NO_ERROR)) {
        ALOGE("Unable to create audio track");
        delete t;
        return NO_INIT;
    }

    ALOGV("setVolume");
    t->setVolume(mLeftVolume, mRightVolume);
    mMsecsPerFrame = 1.e3 / (float) sampleRate;
    mLatency = t->latency();
    mTrack = t;
    return NO_ERROR;
}

void VideoEditorPlayer::VeAudioOutput::start() {

    ALOGV("start");
    if (mTrack) {
        mTrack->setVolume(mLeftVolume, mRightVolume);
        mTrack->start();
        mTrack->getPosition(&mNumFramesWritten);
    }
}

void VideoEditorPlayer::VeAudioOutput::snoopWrite(
    const void* buffer, size_t size) {
    // Visualization buffers not supported
    return;

}

ssize_t VideoEditorPlayer::VeAudioOutput::write(
     const void* buffer, size_t size) {

    LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");

    //ALOGV("write(%p, %u)", buffer, size);
    if (mTrack) {
        snoopWrite(buffer, size);
        ssize_t ret = mTrack->write(buffer, size);
        mNumFramesWritten += ret / 4; // assume 16 bit stereo
        return ret;
    }
    return NO_INIT;
}

void VideoEditorPlayer::VeAudioOutput::stop() {

    ALOGV("stop");
    if (mTrack) mTrack->stop();
}

void VideoEditorPlayer::VeAudioOutput::flush() {

    ALOGV("flush");
    if (mTrack) mTrack->flush();
}

void VideoEditorPlayer::VeAudioOutput::pause() {

    ALOGV("VeAudioOutput::pause");
    if (mTrack) mTrack->pause();
}

void VideoEditorPlayer::VeAudioOutput::close() {

    ALOGV("close");
    delete mTrack;
    mTrack = 0;
}

void VideoEditorPlayer::VeAudioOutput::setVolume(float left, float right) {

    ALOGV("setVolume(%f, %f)", left, right);
    mLeftVolume = left;
    mRightVolume = right;
    if (mTrack) {
        mTrack->setVolume(left, right);
    }
}

// static
void VideoEditorPlayer::VeAudioOutput::CallbackWrapper(
        int event, void *cookie, void *info) {
    //ALOGV("VeAudioOutput::callbackwrapper");
    if (event != AudioTrack::EVENT_MORE_DATA) {
        return;
    }

    VeAudioOutput *me = (VeAudioOutput *)cookie;
    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;

    size_t actualSize = (*me->mCallback)(
            me, buffer->raw, buffer->size, me->mCallbackCookie);

    buffer->size = actualSize;

    if (actualSize > 0) {
        me->snoopWrite(buffer->raw, actualSize);
    }
}

status_t VideoEditorPlayer::VeAudioOutput::dump(int fd, const Vector<String16>& args) const
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    result.append(" VeAudioOutput\n");
    snprintf(buffer, SIZE-1, "  stream type(%d), left - right volume(%f, %f)\n",
            mStreamType, mLeftVolume, mRightVolume);
    result.append(buffer);
    snprintf(buffer, SIZE-1, "  msec per frame(%f), latency (%d)\n",
            mMsecsPerFrame, mLatency);
    result.append(buffer);
    ::write(fd, result.string(), result.size());
    if (mTrack != 0) {
        mTrack->dump(fd, args);
    }
    return NO_ERROR;
}

int VideoEditorPlayer::VeAudioOutput::getSessionId() const {

    return mSessionId;
}

}  // namespace android
