/*
 * 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<IGraphicBufferProducer> &bufferProducer) {
    ALOGV("setVideoSurfaceTexture");

    mPlayer->setSurfaceTexture(bufferProducer);
    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) {
    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,
        const audio_offload_info_t *offloadInfo) {

    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 != 0) close();
    uint32_t afSampleRate;
    size_t 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;
        }
    }

    sp<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");
        return NO_INIT;
    }

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

status_t VideoEditorPlayer::VeAudioOutput::start() {

    ALOGV("start");
    if (mTrack != 0) {
        mTrack->setVolume(mLeftVolume, mRightVolume);
        status_t status = mTrack->start();
        if (status == NO_ERROR) {
            mTrack->getPosition(&mNumFramesWritten);
        }
        return status;
    }
    return NO_INIT;
}

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 != 0) {
        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 != 0) mTrack->stop();
}

void VideoEditorPlayer::VeAudioOutput::flush() {

    ALOGV("flush");
    if (mTrack != 0) mTrack->flush();
}

void VideoEditorPlayer::VeAudioOutput::pause() {

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

void VideoEditorPlayer::VeAudioOutput::close() {

    ALOGV("close");
    mTrack.clear();
}

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

    ALOGV("setVolume(%f, %f)", left, right);
    mLeftVolume = left;
    mRightVolume = right;
    if (mTrack != 0) {
        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,
            MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER);

    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;
}

uint32_t VideoEditorPlayer::VeAudioOutput::getSampleRate() const {
    if (mMsecsPerFrame == 0) {
        return 0;
    }
    return (uint32_t)(1.e3 / mMsecsPerFrame);
}

}  // namespace android
