#include "ImageIO.h"

CImageIO::CImageIO(uint nFrame, uint nWidth, uint nHeight)
{
    m_pRecoder = nullptr;
    m_nFrameRate = nFrame;
    m_nWidth = nWidth;
    m_nHeight = nHeight;

    m_iMat = cv::Mat::zeros(m_nHeight,m_nWidth,CV_8UC3);

    m_nNextStreamIskeyFrame = 0;
}

CImageIO::~CImageIO()
{
    SetFinishRecordFlag();
}

uint CImageIO::GetFrameRate()
{
    return m_nFrameRate;
}

uint CImageIO::GetWidth()
{
    return m_nWidth;
}

uint CImageIO::GetHeight()
{
    return m_nHeight;
}

cv::Mat CImageIO::ReadCVMat(bool &bKeyFrame)
{
    if(m_nNextStreamIskeyFrame > 0)
    {
        bKeyFrame = true;
        m_nNextStreamIskeyFrame--;
    }
    else
    {
        bKeyFrame = false;
    }

    return m_iMat;
}

bool CImageIO::WriteCVMat(const cv::Mat &iMat)
{
    if(m_nWidth != iMat.cols ||
            m_nHeight != iMat.rows)
        return false;

    iMat.copyTo(m_iMat);
    return true;
}

void CImageIO::SetKeyFrameFlag()
{
    std::cout << "set key flag." << std::endl;
    m_nNextStreamIskeyFrame = 3;
}

bool CImageIO::StartRecording(const std::string &strFileName)
{
    if(strFileName.empty())
        return false;

    if(m_pRecoder)
        return false;

    m_pRecoder = new CMediaRecoder;

    bool bRet = m_pRecoder->StartRecode(m_nFrameRate,m_nWidth,m_nHeight,strFileName);
    if(bRet)
    {
        m_bFinishFlag = false;
        SetKeyFrameFlag();
        std::cout << "start record file." << std::endl;
    }
    return bRet;
}

bool CImageIO::HandleEncodeAVPacket(AVPacket *pPacket,bool bKeyFrame)
{
    if(m_pRecoder)
    {
        if(m_bFinishFlag)
        {
            std::cout << "finish record file." << std::endl;
            m_bFinishFlag = false;
            return FinishRecording();
        }
        return m_pRecoder->RecoderPacket(pPacket,bKeyFrame);
    }

    return false;
}

bool CImageIO::SetFinishRecordFlag()
{
    if(m_pRecoder)
    {
        m_bFinishFlag = true;
        while(m_bFinishFlag)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    }

    return true;
}

bool CImageIO::FinishRecording()
{
    if(m_pRecoder)
    {
        m_pRecoder->FinishRecode();
        delete m_pRecoder;
        m_pRecoder = nullptr;
        return true;
    }

    return false;
}


