//
// Created by chenjinyi on 2024/10/31.
//

#ifndef ASP_PLAYER_H
#define ASP_PLAYER_H

#include "AspClientDefine.h"
#include <stdint.h>
#include <functional>

namespace wuying {
namespace asp {

enum STATUS {
    // The requested action was completed successfully.
    RET_OK = 0,

    // A generic error occurred while executing the function.
    RET_ERROR = 1,

    // The requested action was not performed
    // because it's not supported by the Mediaplayer.
    RET_NOT_SUPPORTED = 2,

    // The requested action was not performed
    // because some resource was not yet initialized or acquired.
    RET_NOT_INITIALIZED = 3,
    // video queue is full
    RET_VIDEO_QUEUE_FULL = 4
};

enum class AspImageFormat {
    YUV420P,
    YUV422P,
    YUV444P,
    RGB24,
    RGBA,
    BGRA,
    ARGB,
    ABGR,
    NV12
};

enum class AspVideoFormat {
    VIDEO_H264 = 0,
    VIDEO_H265 = 1,
    VIDEO_VP9 = 2,
    VIDEO_MJPEG = 3,
};

enum AspFrameType {
    ASP_FRAME_UNDEFINED = 0,
    ASP_FRAME_IFRAME = (1 << 0),
    ASP_FRAME_PFRAME = (1 << 1),
    ASP_FRAME_SCALE= (1 << 2),
};

enum class SourceType {
    VIDEO,
    AUDIO
};

typedef std::function<void()> ReleaseBuffer;

struct DecodedDataVideo {
    uint32_t frameId;
    uint8_t* frame;
    uint32_t width;
    uint32_t height;
    AspImageFormat format;
};

struct DecodedDataAudio {
    int sample;
    int channels;
    uint32_t size;
    uint8_t *data;
} ;

struct DecodedData {
    SourceType type;

    union {
        DecodedDataVideo video;
        DecodedDataAudio audio;
    };

    ReleaseBuffer releaseBuffer;
};

enum class AspAudioMode {
    PCM = 1,
    OPUS = 3
};

enum class AspAudioFormat {
    RAW = 1,
    OPUS = 3
};

enum AspAudioReadType {
    PUSH,
    PULL
};

typedef std::function<void(DecodedData &decodedDate)> DecodeCallback;

struct DataSourceVideo {
    uint32_t left;
    uint32_t top;
    uint32_t width;
    uint32_t height;
    AspVideoFormat codecType;
};

struct DataSourceAudio {
    AspAudioMode mode;
    AspAudioFormat format;
    AspAudioReadType readType;
    uint32_t channels;
    uint32_t frequency;
    uint32_t neteqMode;
    void* user;
};

struct DataSource {
    SourceType type;

    union {
        DataSourceVideo video;
        DataSourceAudio audio;
    };

    DecodeCallback callback;
};

struct EncodedDataVideo {
    uint32_t frameId;
    uint32_t size;
    uint32_t mmTime;
    AspFrameType frameType;
    uint8_t* frame;
};

struct EncodedDataAudio {
    uint8_t* frame;
    uint32_t size;
    uint32_t mmtime;
    uint32_t frequency;
    AspAudioMode mode;
    AspAudioFormat format;
    uint32_t channels;
};

struct EncodedData {
    SourceType type;
    
    union {
        EncodedDataVideo video;
        EncodedDataAudio audio;
    };
};

class ASP_CLIENT_SDK_API AspPlayer {
public:
    virtual STATUS addDateSource(uint32_t sourceId, DataSource &dataSource) = 0;
    virtual STATUS pushEncodedData(uint32_t sourceId, EncodedData &data) = 0;
    virtual STATUS removeDateSource(uint32_t sourceId) = 0;

    virtual STATUS play(const uint32_t& sourceId) = 0;
    virtual STATUS pause(const uint32_t& sourceId) = 0;

    virtual STATUS setVolume(const uint32_t& sourceId, const float& volume) = 0;
    virtual STATUS setMute(const uint32_t& sourceId, bool isMute) = 0;

};

}
}

#endif //ASP_PLAYER_H
