#include "TestImgEngine.h"

#include <iostream>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <stdarg.h>
#include <sys/time.h>
#include <string.h>
#include <vector>
#include <memory>

using namespace std;
using namespace ai_matrix;

TestImgEngine::TestImgEngine() {}
TestImgEngine::~TestImgEngine() {}


APP_ERROR TestImgEngine::Init()
{
    strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
    dataSourceConfig_ = MyYaml::GetIns()->GetDataSourceConfigById(engineId_); //获取摄像机参数
    
    width_ = IMAGE_WIDTH, height_ = IMAGE_HEIGHT;

    LogInfo << "engineId_:" << engineId_ << " TestImgEngine Init ok";
    return APP_ERR_OK;
}


APP_ERROR TestImgEngine::DeInit()
{    
    LogInfo << "engineId_:" << engineId_ << " TestImgEngine DeInit ok";
    return APP_ERR_OK;

}

//测试jpeg解码时打开,并修改相应的yaml配置引擎间通信
#if 0
APP_ERROR TestImgEngine::Process()
{
    int iRet = APP_ERR_OK;
    uint64_t u64count_num = 0;
    while (!isStop_)
    {
        // std::cout<<"Enter Read Image Thread "<<++u64count_num<<" Times!"<<std::endl;
        // std::cout<<"Read Image Thread ID: "<<std::this_thread::get_id()<<std::endl;
        //读取图像
        std::string jpeg_img_file_name = MyYaml::GetIns()->GetStringValue("jpeg_image_file_name");

        //从本地文件读取jpg图像并构造jpeg数据
        void* pJPEGBuffer = nullptr;
		
        FILE *jpeg_fp;
        jpeg_fp = fopen(jpeg_img_file_name.c_str(), "r");
        if (!jpeg_fp)
        {
            std::cerr<<"Can not open "<<jpeg_img_file_name.c_str()<<std::endl;
        }
        fseek(jpeg_fp, 0L, SEEK_END);
        unsigned int pJPEGBuffer_Size = ftell(jpeg_fp);
        // printf("the jpg image data len: %d\n", pJPEGBuffer_Size);
        // std::cout<<"the jpg image data len: "<<pJPEGBuffer_Size<<std::endl;
        fseek(jpeg_fp, 0L, SEEK_SET);
		pJPEGBuffer = new uint8_t[pJPEGBuffer_Size];
        fread((char*)pJPEGBuffer, 1, pJPEGBuffer_Size, jpeg_fp);
        fclose(jpeg_fp);

        std::shared_ptr<FrameData> pJPEGFrameData = std::make_shared<FrameData>();

        //组织数据,压入下一引擎
        pJPEGFrameData->iDataSource = engineId_;
        pJPEGFrameData->iSize = pJPEGBuffer_Size;
        pJPEGFrameData->pData.reset(pJPEGBuffer, [](void* data){if(data) {delete[] data; data = nullptr;}}); //智能指针管理内存
        // pJPEGFrameData->pData.reset(pJPEGBuffer, Deleter); //智能指针管理内存
        pJPEGFrameData->i64TimeStamp =  MyUtils::getins()->GetCurrentTimeMillis();

        #if 1
        iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pJPEGFrameData));
        if (iRet != APP_ERR_OK){
			LogError << "push the jpeg image data failed...";
            std::cerr<<"push the jpeg image data failed..."<<std::endl;
		}else{
            // std::cout<<"push the jpeg image data success!"<<std::endl;
        }
        #endif

        usleep(30 * 1000);
    }
}
#else
//测试H264编码或者jpeg编码打开,并修改相应的yaml配置引擎间通信
APP_ERROR TestImgEngine::Process()
{
    int iRet = APP_ERR_OK;
    uint64_t u64count_num = 0;
    while (!isStop_)
    {
        // std::cout<<"Enter Read Image Thread "<<++u64count_num<<" Times!"<<std::endl;
        // std::cout<<"Read Image Thread ID: "<<std::this_thread::get_id()<<std::endl;

        //读取图像
        std::string yuv420m_img_file_name = MyYaml::GetIns()->GetStringValue("yuv420m_image_file_name");

         //从本地文件读取yuv420m图像并构造yuv420m数据
        void* pYUV420MBuffer = nullptr;

        FILE *yuv420m_fp;
        yuv420m_fp = fopen(yuv420m_img_file_name.c_str(), "rb");
        if (!yuv420m_fp)
        {
            std::cerr<<"Can not open "<<yuv420m_img_file_name.c_str()<<std::endl;
        }
        fseek(yuv420m_fp, 0L, SEEK_END);
        unsigned int pYUV420MBuffer_Size = ftell(yuv420m_fp);
        // printf("test.yuv filesize = %d\n", pYUV420MBuffer_Size);
        // std::cout<<"test.yuv filesize = "<<pYUV420MBuffer_Size<<std::endl;
        fseek(yuv420m_fp, 0L, SEEK_SET);
        pYUV420MBuffer = new uint8_t[pYUV420MBuffer_Size];
        fread((char*)pYUV420MBuffer, 1, pYUV420MBuffer_Size, yuv420m_fp);
        fclose(yuv420m_fp);

        std::shared_ptr<FrameData> pYUV420MFrameData = std::make_shared<FrameData>();

        //组织数据,压入下一引擎
        pYUV420MFrameData->iDataSource = engineId_;
        pYUV420MFrameData->iSize = pYUV420MBuffer_Size;
        pYUV420MFrameData->pData.reset(pYUV420MBuffer, [](void* data){if(data) {delete[] data; data = nullptr;}}); //智能指针管理内存
        // pYUV420MFrameData->pData.reset(pYUV420MBuffer, Deleter); //智能指针管理内存
        pYUV420MFrameData->i64TimeStamp =  MyUtils::getins()->GetCurrentTimeMillis();

        #if 1
        iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pYUV420MFrameData));
        if (iRet != APP_ERR_OK){
			LogError << "push the yuv420m image data failed...";
            std::cerr<<"push the yuv420m image data failed..."<<std::endl;
		}else{
            // std::cout<<"push the yuv420m image data success!"<<std::endl;
        }
        #endif

        usleep(30 * 1000);
    }
}
#endif
