#pragma once
#include "image.h"
#include "serializer.h"
#include "util.h"

class MP4Encoder : public Serializer::Type
{
    struct Frame
    {
        enum class kType : uint8_t { IFrame, PFrame, Unknown };
        kType type;
        std::vector<uint8_t> data;
    };
    struct Header
    {
        std::vector<uint8_t> SPS_data;
        std::vector<uint8_t> PPS_data;
        uint8_t avc_profile;
        uint8_t avc_compat;
        uint8_t avc_level;
    };
    class ISVCEncoder* m_encoder = nullptr;
    int m_width = 0;
    int m_height = 0;
    int m_bitrate = 1000 << 10;
    float m_framerate = 0;
    Header m_header;
    std::vector<Frame> m_frames;
    std::vector<uint8_t, AlignmentAllocator<uint8_t, 16>> m_yuv_buffer;
public:
    ~MP4Encoder();
    bool init() noexcept;
    bool init(int width, int height, int fps, int bitrate) noexcept;
    bool encode(const Image& rgba) noexcept;
    bool write_mp4(const std::string& filename) const noexcept;
    void destroy() noexcept;
    int frames_count() const noexcept { return m_frames.size(); }
    glm::ivec2 frame_size() const noexcept { return { m_width, m_height }; }
    virtual bool read(BinaryStreamReader& r) override;
    virtual void write(BinaryStreamWriter& w) const override;
};
