/*
 * 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 "BpMediaSource"
#include <utils/Log.h>

#include <inttypes.h>
#include <stdint.h>
#include <sys/types.h>

#include <binder/Parcel.h>
#include <media/IMediaSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>

namespace android {

enum {
    START = IBinder::FIRST_CALL_TRANSACTION,
    STOP,
    PAUSE,
    GETFORMAT,
    READ,
    RELEASE_BUFFER
};

enum {
    NULL_BUFFER,
    SHARED_BUFFER,
    INLINE_BUFFER
};

class RemoteMediaBufferReleaser : public BBinder {
public:
    RemoteMediaBufferReleaser(MediaBuffer *buf) {
        mBuf = buf;
    }
    ~RemoteMediaBufferReleaser() {
        if (mBuf) {
            ALOGW("RemoteMediaBufferReleaser dtor called while still holding buffer");
            mBuf->release();
        }
    }
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0) {
        if (code == RELEASE_BUFFER) {
            mBuf->release();
            mBuf = NULL;
            return OK;
        } else {
            return BBinder::onTransact(code, data, reply, flags);
        }
    }
private:
    MediaBuffer *mBuf;
};


class RemoteMediaBufferWrapper : public MediaBuffer {
public:
    RemoteMediaBufferWrapper(sp<IMemory> mem, sp<IBinder> source);
protected:
    virtual ~RemoteMediaBufferWrapper();
private:
    sp<IMemory> mMemory;
    sp<IBinder> mRemoteSource;
};

RemoteMediaBufferWrapper::RemoteMediaBufferWrapper(sp<IMemory> mem, sp<IBinder> source)
: MediaBuffer(mem->pointer(), mem->size()) {
    mMemory = mem;
    mRemoteSource = source;
}

RemoteMediaBufferWrapper::~RemoteMediaBufferWrapper() {
    mMemory.clear();
    // Explicitly ask the remote side to release the buffer. We could also just clear
    // mRemoteSource, but that doesn't immediately release the reference on the remote side.
    Parcel data, reply;
    mRemoteSource->transact(RELEASE_BUFFER, data, &reply);
    mRemoteSource.clear();
}

class BpMediaSource : public BpInterface<IMediaSource> {
public:
    BpMediaSource(const sp<IBinder>& impl)
        : BpInterface<IMediaSource>(impl)
    {
    }

    virtual status_t start(MetaData *params) {
        ALOGV("start");
        Parcel data, reply;
        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
        if (params) {
            params->writeToParcel(data);
        }
        status_t ret = remote()->transact(START, data, &reply);
        if (ret == NO_ERROR && params) {
            ALOGW("ignoring potentially modified MetaData from start");
            ALOGW("input:");
            params->dumpToLog();
            sp<MetaData> meta = MetaData::createFromParcel(reply);
            ALOGW("output:");
            meta->dumpToLog();
        }
        return ret;
    }

    virtual status_t stop() {
        ALOGV("stop");
        Parcel data, reply;
        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
        return remote()->transact(STOP, data, &reply);
    }

    virtual sp<MetaData> getFormat() {
        ALOGV("getFormat");
        Parcel data, reply;
        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
        status_t ret = remote()->transact(GETFORMAT, data, &reply);
        if (ret == NO_ERROR) {
            mMetaData = MetaData::createFromParcel(reply);
            return mMetaData;
        }
        return NULL;
    }

    virtual status_t read(MediaBuffer **buffer, const ReadOptions *options) {
        ALOGV("read");
        Parcel data, reply;
        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
        if (options) {
            data.writeByteArray(sizeof(*options), (uint8_t*) options);
        }
        status_t ret = remote()->transact(READ, data, &reply);
        if (ret != NO_ERROR) {
            return ret;
        }
        // wrap the returned data in a MediaBuffer
        ret = reply.readInt32();
        int32_t buftype = reply.readInt32();
        if (buftype == SHARED_BUFFER) {
            sp<IBinder> remote = reply.readStrongBinder();
            sp<IBinder> binder = reply.readStrongBinder();
            sp<IMemory> mem = interface_cast<IMemory>(binder);
            if (mem == NULL) {
                ALOGE("received NULL IMemory for shared buffer");
            }
            size_t offset = reply.readInt32();
            size_t length = reply.readInt32();
            MediaBuffer *buf = new RemoteMediaBufferWrapper(mem, remote);
            buf->set_range(offset, length);
            buf->meta_data()->updateFromParcel(reply);
            *buffer = buf;
        } else if (buftype == NULL_BUFFER) {
            ALOGV("got status %d and NULL buffer", ret);
            *buffer = NULL;
        } else {
            int32_t len = reply.readInt32();
            ALOGV("got status %d and len %d", ret, len);
            *buffer = new MediaBuffer(len);
            reply.read((*buffer)->data(), len);
            (*buffer)->meta_data()->updateFromParcel(reply);
        }
        return ret;
    }

    virtual status_t pause() {
        ALOGV("pause");
        Parcel data, reply;
        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
        return remote()->transact(PAUSE, data, &reply);
    }

    virtual status_t setBuffers(const Vector<MediaBuffer *> & buffers __unused) {
        ALOGV("setBuffers NOT IMPLEMENTED");
        return ERROR_UNSUPPORTED; // default
    }

private:
    // NuPlayer passes pointers-to-metadata around, so we use this to keep the metadata alive
    // XXX: could we use this for caching, or does metadata change on the fly?
    sp<MetaData> mMetaData;

};

IMPLEMENT_META_INTERFACE(MediaSource, "android.media.IMediaSource");

#undef LOG_TAG
#define LOG_TAG "BnMediaSource"

status_t BnMediaSource::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch (code) {
        case START: {
            ALOGV("start");
            CHECK_INTERFACE(IMediaSource, data, reply);
            sp<MetaData> meta;
            if (data.dataAvail()) {
                meta = MetaData::createFromParcel(data);
            }
            status_t ret = start(meta.get());
            if (ret == NO_ERROR && meta != NULL) {
                meta->writeToParcel(*reply);
            }
            return ret;
        }
        case STOP: {
            ALOGV("stop");
            CHECK_INTERFACE(IMediaSource, data, reply);
            return stop();
        }
        case PAUSE: {
            ALOGV("pause");
            CHECK_INTERFACE(IMediaSource, data, reply);
            return pause();
        }
        case GETFORMAT: {
            ALOGV("getFormat");
            CHECK_INTERFACE(IMediaSource, data, reply);
            sp<MetaData> meta = getFormat();
            if (meta != NULL) {
                meta->writeToParcel(*reply);
                return NO_ERROR;
            }
            return UNKNOWN_ERROR;
        }
        case READ: {
            ALOGV("read");
            CHECK_INTERFACE(IMediaSource, data, reply);
            status_t ret;
            MediaBuffer *buf = NULL;
            ReadOptions opts;
            uint32_t len;
            if (data.readUint32(&len) == NO_ERROR &&
                    len == sizeof(opts) && data.read((void*)&opts, len) == NO_ERROR) {
                ret = read(&buf, &opts);
            } else {
                ret = read(&buf, NULL);
            }

            reply->writeInt32(ret);
            if (buf != NULL) {
                size_t usedSize = buf->range_length();
                // even if we're using shared memory, we might not want to use it, since for small
                // sizes it's faster to copy data through the Binder transaction
                if (buf->mMemory != NULL && usedSize >= 64 * 1024) {
                    ALOGV("buffer is using shared memory: %zu", usedSize);
                    reply->writeInt32(SHARED_BUFFER);
                    RemoteMediaBufferReleaser *wrapper = new RemoteMediaBufferReleaser(buf);
                    reply->writeStrongBinder(wrapper);
                    reply->writeStrongBinder(IInterface::asBinder(buf->mMemory));
                    reply->writeInt32(buf->range_offset());
                    reply->writeInt32(usedSize);
                    buf->meta_data()->writeToParcel(*reply);
                } else {
                    // buffer is not in shared memory, or is small: copy it
                    if (buf->mMemory != NULL) {
                        ALOGV("%zu shared mem available, but only %zu used", buf->mMemory->size(), buf->range_length());
                    }
                    reply->writeInt32(INLINE_BUFFER);
                    reply->writeByteArray(buf->range_length(), (uint8_t*)buf->data() + buf->range_offset());
                    buf->meta_data()->writeToParcel(*reply);
                    buf->release();
                }
            } else {
                ALOGV("ret %d, buf %p", ret, buf);
                reply->writeInt32(NULL_BUFFER);
            }
            return NO_ERROR;
        }
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

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

IMediaSource::ReadOptions::ReadOptions() {
    reset();
}

void IMediaSource::ReadOptions::reset() {
    mOptions = 0;
    mSeekTimeUs = 0;
    mLatenessUs = 0;
    mNonBlocking = false;
}

void IMediaSource::ReadOptions::setNonBlocking() {
    mNonBlocking = true;
}

void IMediaSource::ReadOptions::clearNonBlocking() {
    mNonBlocking = false;
}

bool IMediaSource::ReadOptions::getNonBlocking() const {
    return mNonBlocking;
}

void IMediaSource::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
    mOptions |= kSeekTo_Option;
    mSeekTimeUs = time_us;
    mSeekMode = mode;
}

void IMediaSource::ReadOptions::clearSeekTo() {
    mOptions &= ~kSeekTo_Option;
    mSeekTimeUs = 0;
    mSeekMode = SEEK_CLOSEST_SYNC;
}

bool IMediaSource::ReadOptions::getSeekTo(
        int64_t *time_us, SeekMode *mode) const {
    *time_us = mSeekTimeUs;
    *mode = mSeekMode;
    return (mOptions & kSeekTo_Option) != 0;
}

void IMediaSource::ReadOptions::setLateBy(int64_t lateness_us) {
    mLatenessUs = lateness_us;
}

int64_t IMediaSource::ReadOptions::getLateBy() const {
    return mLatenessUs;
}


}  // namespace android

