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

#ifndef CODEC_BASE_H_

#define CODEC_BASE_H_

#include <memory>

#include <stdint.h>

#define STRINGIFY_ENUMS

#include <media/ICrypto.h>
#include <media/IOMX.h>
#include <media/MediaCodecInfo.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/ColorUtils.h>
#include <media/hardware/HardwareAPI.h>

#include <utils/NativeHandle.h>

#include <system/graphics.h>
#include <android/media/IDescrambler.h>

namespace android {
using namespace media;
class BufferChannelBase;
class BufferProducerWrapper;
class MediaCodecBuffer;
struct PersistentSurface;
struct RenderedFrameInfo;
class Surface;

struct CodecBase : public AHandler, /* static */ ColorUtils {
    /**
     * This interface defines events firing from CodecBase back to MediaCodec.
     * All methods must not block.
     */
    class CodecCallback {
    public:
        virtual ~CodecCallback() = default;

        /**
         * Notify MediaCodec for seeing an output EOS.
         *
         * @param err the underlying cause of the EOS. If the value is neither
         *            OK nor ERROR_END_OF_STREAM, the EOS is declared
         *            prematurely for that error.
         */
        virtual void onEos(status_t err) = 0;
        /**
         * Notify MediaCodec that start operation is complete.
         */
        virtual void onStartCompleted() = 0;
        /**
         * Notify MediaCodec that stop operation is complete.
         */
        virtual void onStopCompleted() = 0;
        /**
         * Notify MediaCodec that release operation is complete.
         */
        virtual void onReleaseCompleted() = 0;
        /**
         * Notify MediaCodec that flush operation is complete.
         */
        virtual void onFlushCompleted() = 0;
        /**
         * Notify MediaCodec that an error is occurred.
         *
         * @param err         an error code for the occurred error.
         * @param actionCode  an action code for severity of the error.
         */
        virtual void onError(status_t err, enum ActionCode actionCode) = 0;
        /**
         * Notify MediaCodec that the underlying component is allocated.
         *
         * @param componentName the unique name of the component specified in
         *                      MediaCodecList.
         */
        virtual void onComponentAllocated(const char *componentName) = 0;
        /**
         * Notify MediaCodec that the underlying component is configured.
         *
         * @param inputFormat   an input format at configure time.
         * @param outputFormat  an output format at configure time.
         */
        virtual void onComponentConfigured(
                const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) = 0;
        /**
         * Notify MediaCodec that the input surface is created.
         *
         * @param inputFormat   an input format at surface creation. Formats
         *                      could change from the previous state as a result
         *                      of creating a surface.
         * @param outputFormat  an output format at surface creation.
         * @param inputSurface  the created surface.
         */
        virtual void onInputSurfaceCreated(
                const sp<AMessage> &inputFormat,
                const sp<AMessage> &outputFormat,
                const sp<BufferProducerWrapper> &inputSurface) = 0;
        /**
         * Notify MediaCodec that the input surface creation is failed.
         *
         * @param err an error code of the cause.
         */
        virtual void onInputSurfaceCreationFailed(status_t err) = 0;
        /**
         * Notify MediaCodec that the component accepted the provided input
         * surface.
         *
         * @param inputFormat   an input format at surface assignment. Formats
         *                      could change from the previous state as a result
         *                      of assigning a surface.
         * @param outputFormat  an output format at surface assignment.
         */
        virtual void onInputSurfaceAccepted(
                const sp<AMessage> &inputFormat,
                const sp<AMessage> &outputFormat) = 0;
        /**
         * Notify MediaCodec that the component declined the provided input
         * surface.
         *
         * @param err an error code of the cause.
         */
        virtual void onInputSurfaceDeclined(status_t err) = 0;
        /**
         * Noitfy MediaCodec that the requested input EOS is sent to the input
         * surface.
         *
         * @param err an error code returned from the surface. If there is no
         *            input surface, the value is INVALID_OPERATION.
         */
        virtual void onSignaledInputEOS(status_t err) = 0;
        /**
         * Notify MediaCodec that output frames are rendered with information on
         * those frames.
         *
         * @param done  a list of rendered frames.
         */
        virtual void onOutputFramesRendered(const std::list<RenderedFrameInfo> &done) = 0;
        /**
         * Notify MediaCodec that output buffers are changed.
         */
        virtual void onOutputBuffersChanged() = 0;
    };

    /**
     * This interface defines events firing from BufferChannelBase back to MediaCodec.
     * All methods must not block.
     */
    class BufferCallback {
    public:
        virtual ~BufferCallback() = default;

        /**
         * Notify MediaCodec that an input buffer is available with given index.
         * When BufferChannelBase::getInputBufferArray() is not called,
         * BufferChannelBase may report different buffers with the same index if
         * MediaCodec already queued/discarded the buffer. After calling
         * BufferChannelBase::getInputBufferArray(), the buffer and index match the
         * returned array.
         */
        virtual void onInputBufferAvailable(
                size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
        /**
         * Notify MediaCodec that an output buffer is available with given index.
         * When BufferChannelBase::getOutputBufferArray() is not called,
         * BufferChannelBase may report different buffers with the same index if
         * MediaCodec already queued/discarded the buffer. After calling
         * BufferChannelBase::getOutputBufferArray(), the buffer and index match the
         * returned array.
         */
        virtual void onOutputBufferAvailable(
                size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
    };
    enum {
        kMaxCodecBufferSize = 8192 * 4096 * 4, // 8K RGBA
    };

    inline void setCallback(std::unique_ptr<CodecCallback> &&callback) {
        mCallback = std::move(callback);
    }
    virtual std::shared_ptr<BufferChannelBase> getBufferChannel() = 0;

    virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;
    virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;
    virtual void initiateCreateInputSurface() = 0;
    virtual void initiateSetInputSurface(
            const sp<PersistentSurface> &surface) = 0;
    virtual void initiateStart() = 0;
    virtual void initiateShutdown(bool keepComponentAllocated = false) = 0;

    // require an explicit message handler
    virtual void onMessageReceived(const sp<AMessage> &msg) = 0;

    virtual status_t queryCapabilities(
            const AString& /*name*/, const AString& /*mime*/, bool /*isEncoder*/,
            sp<MediaCodecInfo::Capabilities>* /*caps*/ /* nonnull */) { return INVALID_OPERATION; }

    virtual status_t setSurface(const sp<Surface>& /*surface*/) { return INVALID_OPERATION; }

    virtual void signalFlush() = 0;
    virtual void signalResume() = 0;

    virtual void signalRequestIDRFrame() = 0;
    virtual void signalSetParameters(const sp<AMessage> &msg) = 0;
    virtual void signalEndOfInputStream() = 0;

    /*
     * Codec-related defines
     */

protected:
    CodecBase() = default;
    virtual ~CodecBase() = default;

    std::unique_ptr<CodecCallback> mCallback;

private:
    DISALLOW_EVIL_CONSTRUCTORS(CodecBase);
};

/**
 * A channel between MediaCodec and CodecBase object which manages buffer
 * passing. Only MediaCodec is expected to call these methods, and
 * underlying CodecBase implementation should define its own interface
 * separately for itself.
 *
 * Concurrency assumptions:
 *
 * 1) Clients may access the object at multiple threads concurrently.
 * 2) All methods do not call underlying CodecBase object while holding a lock.
 * 3) Code inside critical section executes within 1ms.
 */
class BufferChannelBase {
public:
    virtual ~BufferChannelBase() = default;

    inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) {
        mCallback = std::move(callback);
    }

    inline void setCrypto(const sp<ICrypto> &crypto) {
        mCrypto = crypto;
    }

    inline void setDescrambler(const sp<IDescrambler> &descrambler) {
        mDescrambler = descrambler;
    }

    /**
     * Queue an input buffer into the buffer channel.
     *
     * @return    OK if successful;
     *            -ENOENT if the buffer is not known (TODO: this should be
     *            handled gracefully in the future, here and below).
     */
    virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
    /**
     * Queue a secure input buffer into the buffer channel.
     *
     * @return    OK if successful;
     *            -ENOENT if the buffer is not known;
     *            -ENOSYS if mCrypto is not set so that decryption is not
     *            possible;
     *            other errors if decryption failed.
     */
    virtual status_t queueSecureInputBuffer(
            const sp<MediaCodecBuffer> &buffer,
            bool secure,
            const uint8_t *key,
            const uint8_t *iv,
            CryptoPlugin::Mode mode,
            CryptoPlugin::Pattern pattern,
            const CryptoPlugin::SubSample *subSamples,
            size_t numSubSamples,
            AString *errorDetailMsg) = 0;
    /**
     * Request buffer rendering at specified time.
     *
     * @param     timestampNs   nanosecond timestamp for rendering time.
     * @return    OK if successful;
     *            -ENOENT if the buffer is not known.
     */
    virtual status_t renderOutputBuffer(
            const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) = 0;
    /**
     * Discard a buffer to the underlying CodecBase object.
     *
     * TODO: remove once this operation can be handled by just clearing the
     * reference.
     *
     * @return    OK if successful;
     *            -ENOENT if the buffer is not known.
     */
    virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
    /**
     * Clear and fill array with input buffers.
     */
    virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
    /**
     * Clear and fill array with output buffers.
     */
    virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;

protected:
    std::unique_ptr<CodecBase::BufferCallback> mCallback;
    sp<ICrypto> mCrypto;
    sp<IDescrambler> mDescrambler;
};

}  // namespace android

#endif  // CODEC_BASE_H_

