/*
 * Copyright (c) 2020, NVIDIA CORPORATION.  All rights reserved.
 *
 * NVIDIA CORPORATION and its licensors retain all intellectual property
 * and proprietary rights in and to this software, related documentation
 * and any modifications thereto.  Any use, reproduction, disclosure or
 * distribution of this software and related documentation without an express
 * license agreement from NVIDIA CORPORATION is strictly prohibited.
 */

#ifndef CIMAGEMANAGER_HPP
#define CIMAGEMANAGER_HPP

// Standard header files
#include <memory>

// SIPL header files
#include "NvSIPLCommon.hpp"
#include "NvSIPLCamera.hpp"

// Sample application header files
#include "CUtils.hpp"

// Other NVIDIA header files
#include "nvscibuf.h"
#include "nvmedia_core.h"
#include "nvmedia_surface.h"
#include "nvmedia_image_nvscibuf.h"

using namespace nvsipl;

#define MAX_NUM_IMAGE_OUTPUTS (3U)

class CImageManager
{
public:
    //! Initialize: allocates image groups and images and registers them with SIPL.
    SIPLStatus Init(INvSIPLCamera *siplCamera, uint32_t index);

    //! Deinitialize: deallocates image groups and images.
    void Deinit();

    //! Destructor: calls Deinit.
    ~CImageManager();

private:
    typedef struct {
        bool enable;
        size_t size;
        INvSIPLClient::ConsumerDesc::OutputType outputType;
        NvSIPLImageAttr imageAttrs;
        std::vector<NvMediaImageGroup *> imageGroups;
        std::vector<NvMediaImage *> images;
        std::vector<NvSciBufObj> sciBufObjs;
    } ImagePool;

    //! Allocates image groups to be used with ICP.
    SIPLStatus AllocateImageGroups(ImagePool &imagePool);

    //! Allocates images to be used with ISP.
    SIPLStatus AllocateImages(ImagePool &imagePool);

    //! Deletes image groups (used with ICP).
    void DeleteImageGroups(ImagePool &imagePool);

    //! Deletes images (used with ISP).
    void DeleteImages(ImagePool &imagePool);

    //! Allocates image groups and images.
    SIPLStatus Allocate();

    //! Registers image groups and images with SIPL.
    SIPLStatus Register();

    INvSIPLCamera *m_siplCamera = nullptr;
    uint32_t m_index = -1U;
    NvMediaDevice *m_nvmDevice = nullptr;
    NvSciBufModule m_sciBufModule = nullptr;
    ImagePool m_imagePools[MAX_NUM_IMAGE_OUTPUTS];
};

#endif // CIMAGEMANAGER_HPP
