c++ 池子

#ifndef EGL_POOL_H
#define EGL_POOL_H
#include "./IBRGPU.h"

#include "./threadsafe_queue.cpp"

class EGL
{
public:
    // 是对实际显示设备的抽象
    EGLDisplay display;
    // 是对用来存储图像的内存区域FrameBuffer 的抽象,包括 Color Buffer, Stencil Buffer ,Depth Buffer。
    EGLContext context;
    // 存储 OpenGL ES绘图的一些状态信息。
    EGLSurface surface;
    xverse::ixve *ixveEncode;
    xverse::ixve *ixveDecode;
    Shader *IBRShader;
    Shader *depthShader;
};

/**
 *   @brief  获取一组EGL参数,并对该组参数进行初始化操作
 */
EGL GetEGL();

class EGLPool
{
public:
    EGLPool(int minSize, int maxSize);
    EGL GetEGL();

private:
    int minSize, maxSize;
    gdface::threadsafe_queue<EGL> gQueue;
    void initPool();
    EGL gen();
    void watchCapacity();
    xverse::ixve *initXveEncode(struct EncodeParam *encodeParam);
    xverse::ixve *initXveDecode();
};
/**
 *   @brief  初始化EGL池子
 *   @param  minSize 最小容量,如果使用过程中池子的容量减小到小于最小容量,
 *                   则会继续像池子中添加新对象
 *   @param  maxSize 最大容量,池子会初始化为最大容量数,
 *                   后续池子的总容量也会小于最大容量
 */
void InitEGLPool(int minSize, int maxSize);

#endif
#include "./IBRGPU.h"
#include "./egl_pool.h"
#include "./threadsafe_queue.cpp"

static EGLPool *globalEGLPool;

/**
 *   @brief  初始化EGL池子
 *   @param  minSize 最小容量,如果使用过程中池子的容量减小到小于最小容量,
 *                   则会继续像池子中添加新对象
 *   @param  maxSize 最大容量,池子会初始化为最大容量数,
 *                   后续池子的总容量也会小于最大容量
 */
void InitEGLPool(int minSize, int maxSize)
{
    globalEGLPool = new EGLPool(minSize, maxSize);
}

/**
 *   @brief  获取一组EGL参数,并对该组参数进行初始化操作
 */
EGL GetEGL()
{

    return globalEGLPool->GetEGL();
}

/**
 *   @param  minSize 最小容量,如果使用过程中池子的容量减小到小于最小容量,
 *                   则会继续像池子中添加新对象
 *   @param  maxSize 最大容量,池子会初始化为最大容量数,
 *                   后续池子的总容量也会小于最大容量
 */
EGLPool::EGLPool(int minSize, int maxSize)
{
    this->minSize = minSize;
    this->maxSize = maxSize;

    this->initPool();
};

EGL EGLPool::GetEGL()
{
    return gQueue.wait_and_pop();
}

/**
 *   @brief  初始化池子
 */
void EGLPool::initPool()
{
    std::cout << "== Init EGLPool == " << maxSize << std::endl;
    for (unsigned int i = 0; i < maxSize; i++)
    {
        gQueue.push(gen());
    }
    std::cout << "== Init EGLPool finish == " << std::endl;
}
/**
 *   @brief   维护池子容量平衡
 *   @details 如果池子的容量减小到小于最小容量,
 *            则会继续像池子中添加max-cuurent的对象个数
 */
void EGLPool::watchCapacity()
{
    if (this->gQueue.size() < this->minSize)
    {
        int maxdiffer = this->maxSize - this->gQueue.size();
        for (unsigned int i = 0; i < maxdiffer; i++)
        {
            gQueue.push(gen());
        }
    }
}

/**
 *   @brief  初始化EGL,并生成EGL信息
 *   @return EGL
 */
EGL EGLPool::gen()
{
    std::cout << "== Init EGL == " << std::endl;
    EGL egl;

    // 1.选择显卡 todo 确定具体要多少设备去加载模型
    static const int MAX_DEVICES = 10;
    EGLDeviceEXT eglDevs[MAX_DEVICES];
    EGLint numDev;
    PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
    eglQueryDevicesEXT(MAX_DEVICES, eglDevs, &numDev);
    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
    // 选择显卡,双显卡0、1可以创建display,会有2、3的额外设备,但是创建出的display为空。
    // 2.获取EGLDisplay
    egl.display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, eglDevs[0], 0);

    // 3.初始化与EGLDisplay之间的连接
    EGLint major, minor; // major 主版本号,minor次版本号
    eglInitialize(egl.display, &major, &minor);

    // 3.获取EGLConfig对象
    EGLint num_con;
    EGLint attrlist[] = {
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
        EGL_NONE};
    EGLConfig config;
    eglChooseConfig(egl.display, attrlist, &config, 1, &num_con);

    // 后面创建的 surface 和 context 要与这个API相匹配
    eglBindAPI(EGL_OPENGL_API);
    egl.surface = eglCreatePbufferSurface(egl.display, config, NULL);
    // 创建上下文
    EGLint contextAttrs[] = {
        EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT,
        EGL_CONTEXT_MAJOR_VERSION, 4,
        EGL_CONTEXT_MINOR_VERSION, 6,
        EGL_NONE};
    egl.context = eglCreateContext(egl.display, config, EGL_NO_CONTEXT, contextAttrs);
    EGLBoolean err1 = eglGetError();
    bool res;
    res = eglMakeCurrent(egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl.context); //自己创建FBO绘制,可以不绑定surface
    // GLAD是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLAD
      std::cout << "== Init EGL =gladLoadGLLoader1= " << std::endl;
    if (!gladLoadGLLoader((GLADloadproc)eglGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        exit(-1);
        ;
    }
     std::cout << "== Init EGL =gladLoadGLLoader2= " << std::endl;
     if (!gladLoadGLLoader((GLADloadproc)eglGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        exit(-1);
        ;
    }

    GetGlobalModel()->setupMesh();


    struct EncodeParam encodeParam;
    encodeParam.fps = 30;
    encodeParam.gop = 32;
    string bitrate = "6m";
    encodeParam.bitrate = bitrate.data();
    egl.ixveEncode = initXveEncode(&encodeParam);
    egl.ixveDecode = initXveDecode();

      std::cout << "init IBR shader" << std::endl;
    egl.IBRShader = new Shader("shader/mesh_based_render_image_shader_Pcf.vert", "shader/mesh_based_render_image_shader_Pcf.frag");
    egl.IBRShader->use();
    egl.IBRShader->setInt("texture_image_0", 0);
    egl.IBRShader->setInt("depthMap_0", 1);
    egl.IBRShader->setInt("texture_image_1", 2);
    egl.IBRShader->setInt("depthMap_1", 3);
    egl.IBRShader->setInt("texture_image_2", 4);
    egl.IBRShader->setInt("depthMap_2", 5);
    egl.IBRShader->setInt("texture_image_3", 6);
    egl.IBRShader->setInt("depthMap_3", 7);
    egl.IBRShader->setInt("texture_image_4", 8);
    egl.IBRShader->setInt("depthMap_4", 9);
    egl.IBRShader->setInt("texture_image_5", 10);
    egl.IBRShader->setInt("depthMap_5", 11);

    std::cout << "init depth shader" << std::endl;
    egl.depthShader = new Shader("shader/mesh_based_depth.vs", "shader/mesh_based_depth.fs");
        std::cout << "== Init EGL Finish == " << std::endl;
    return egl;
}

xverse::ixve *EGLPool::initXveEncode(struct EncodeParam *encodeParam)
{
    xverse::ixve *ixveEncode;
    std::cout << "init xve encode " << std::endl;
    CreateXVE(&ixveEncode);
    xverse::EngineParam engine_param = {
        .codec_param =
            {
                .extra_dpb_size = 0,
                .nalu_buf_cnt = 0,
                .color_space = xverse::emColorSpace::kColorSpaceNone, // not effective when dxva2/nvenc is used.
                .nv_enc_params =
                    {
                        .width = uint32_t(1280),
                        .height = uint32_t(720),
                        //.fps = 30,
                        .fps = uint32_t(encodeParam->fps),
                        .gop = uint32_t(encodeParam->gop),
                        //.gop = uint32_t(encodeParam->gop),
                        // .buffer_format = (char *)"iyuv",  // todo: use codec_param.color_space instead
                        .buffer_format = (char *)"abgr", // todo: use codec_param.color_space instead
                                                         //  .avg_bitrate = (char *)"4m",
                        .avg_bitrate = encodeParam->bitrate,
                    },
                // .nv_enc_category = xverse::NvEncCategories::kNvEncCateUsingCuda,
                .nv_enc_category = xverse::NvEncCategories::kNvEncCateUsingEGL,
                .pixve = ixveEncode,
            },
        .codec_type =
            {
                // .hard_soft = xverse::emCodecTypeHardSoft::kSoftware,
                .hard_soft = xverse::emCodecTypeHardSoft::kHardware,
                .enc_dec = xverse::emCodecTypeEncDec::kEncoder,
                .standard = xverse::emCodecTypeStd::kH264,
            },
        .log_level = xverse::emLogLevel::kVerbose,
        .log_callback = nullptr,
    };
    ixveEncode->Open(&engine_param);
    std::cout << "init xve encode finished " << std::endl;
    return ixveEncode;
}

xverse::ixve *EGLPool::initXveDecode()
{
    xverse::ixve *ixveDecode;
    std::cout << "init xve decode " << std::endl;
    CreateXVE(&ixveDecode);
    bool init_cuda_in_sdk = false;
    CUcontext cuContext = nullptr;
    string log_filename = "/tmp/ibr.log";
    if (!init_cuda_in_sdk)
    {
        std::cout << "init cuda: " << std::endl;
        // todo: encapsulate into a utility function
        CUresult cuda_res = cuInit(0);
        if (cuda_res < 0)
        {
            std::cout << "error cuinit\n";
        }
        int nGpu = 0;
        cuda_res = cuDeviceGetCount(&nGpu);
        if (cuda_res < 0)
        {
            std::cout << "error cuinit\n";
        }
        int iGpu = 0;
        if (iGpu < 0 || iGpu >= nGpu)
        {
            std::cout << "GPU ordinal out of range. Should be within [" << 0 << ", " << nGpu - 1 << "]" << std::endl;
        }

        CUdevice cuDevice = 0;
        cuda_res = cuDeviceGet(&cuDevice, iGpu);
        if (cuda_res < 0)
        {
            std::cout << "error cuinit\n";
        }
        char szDeviceName[80];
        cuda_res = cuDeviceGetName(szDeviceName, sizeof(szDeviceName), cuDevice);
        if (cuda_res < 0)
        {
            std::cout << "error cuinit\n";
        }
        std::cout << "[INFO] GPU in use: " << szDeviceName << std::endl;
        cuda_res = cuCtxCreate(&cuContext, 0, cuDevice);
        if (cuda_res < 0)
        {
            std::cout << "error cuinit\n";
        }
    }
    std::cout << "init xve decode: \n";
    xverse::EngineParam engine_param = {
        .codec_param =
            {
                .extra_dpb_size = 0,
                .nalu_buf_cnt = 0,
                .color_space = xverse::emColorSpace::kColorSpaceI420, // not effective when dxva2/NVDEC is used.
                .pixve = ixveDecode,
            },
        .codec_type =
            {
                .hard_soft = xverse::emCodecTypeHardSoft::kHardware,
                .enc_dec = xverse::emCodecTypeEncDec::kDecoder,
                .standard = xverse::emCodecTypeStd::kH265,
            },
        .log_level = xverse::emLogLevel::kVerbose,
        .log_callback = nullptr,
        .log_filename = log_filename.c_str(),
        .init_cuda_inside = init_cuda_in_sdk,
        .cu_ctx = (init_cuda_in_sdk ? nullptr : &cuContext),
        .nv_dec_output_in_device_mem = 1};
    ixveDecode->Open(&engine_param);
    std::cout << "init xve decode finished " << std::endl;
    return ixveDecode;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值