#include "CFramedLiveSource.h"

CFramedLiveSource::CFramedLiveSource(UsageEnvironment& env,CImageIO *piImgIO)
    :FramedSource(env)
{
    m_nLeftBufferLen = 0;
    m_pTempBuffer = NULL;
    m_nBufferLen = 0;

    fMaxPayloadSize = 2000 * 1024;
    fOutputBuffer = new unsigned char[fMaxPayloadSize];

    m_nFrameRate = piImgIO->GetFrameRate();
    m_piImageHandler = new CImageHandler(piImgIO);
    m_piCVMatIO = piImgIO;
}

CFramedLiveSource* CFramedLiveSource::createNew(UsageEnvironment& env,CImageIO *piImgIO)
{
    CFramedLiveSource* newSource = new CFramedLiveSource(env,piImgIO);

    return newSource;
}

CFramedLiveSource::~CFramedLiveSource()
{
    m_nLeftBufferLen = 0;
    m_pTempBuffer = NULL;

    delete[] fOutputBuffer;
    delete m_piImageHandler;
}

void CFramedLiveSource::doGetNextFrame()
{
    fFrameSize = 0;
    if (m_piImageHandler)
    {
        if (m_pTempBuffer == NULL || m_nLeftBufferLen == 0)
        {
            uint8_t *pBuffer = fOutputBuffer;
            int nBufferLen = fMaxPayloadSize;

            m_piImageHandler->GetFrameData(&pBuffer,&nBufferLen);

            //std::cout << "get frame: " << nBufferLen << std::endl;
            if (pBuffer != NULL && nBufferLen > 0)
            {
                m_pTempBuffer = pBuffer;
                m_nBufferLen = nBufferLen;
                m_nLeftBufferLen = nBufferLen;
            }
        }

        if (m_pTempBuffer != NULL || m_nLeftBufferLen > 0)
        {
            int nCopyLen = m_nLeftBufferLen>fMaxSize ? fMaxSize:m_nLeftBufferLen;
            memcpy((unsigned char*)fTo, m_pTempBuffer + m_nBufferLen - m_nLeftBufferLen, nCopyLen);

            m_nLeftBufferLen -= nCopyLen;
            fFrameSize = nCopyLen;
            if (m_nLeftBufferLen == 0)
            {
                m_nLeftBufferLen = 0;
                m_pTempBuffer = NULL;
                m_nBufferLen = 0;
            }
        }
    }

    double nFrameRate = m_piCVMatIO->GetFrameRate();
    fDurationInMicroseconds = 1000000 / nFrameRate;
    nextTask() = envir().taskScheduler().scheduleDelayedTask(0,
                   (TaskFunc*)FramedSource::afterGetting, this);
    return;
}


