bool HimppVideoISP::registerAlgorithm()
{
	ALG_LIB_S stLib;
	HI_S32 s32Ret;

	stLib.s32Id = 0;
	strcpy(stLib.acLibName, HI_AE_LIB_NAME);
	if ((s32Ret = HI_MPI_AE_Register(&stLib)) != HI_SUCCESS) {
		HIMPP_PRINT("HI_MPI_AE_Register failed [%#x]\n", s32Ret);
		return false;
	}

	stLib.s32Id = 0;
	strcpy(stLib.acLibName, HI_AWB_LIB_NAME);
	if ((s32Ret = HI_MPI_AWB_Register(&stLib)) != HI_SUCCESS) {
		HIMPP_PRINT("HI_MPI_AWB_Register failed [%#x]\n", s32Ret);
		return false;
	}

	stLib.s32Id = 0;
	strcpy(stLib.acLibName, HI_AF_LIB_NAME);
	if ((s32Ret = HI_MPI_AF_Register(&stLib)) != HI_SUCCESS) {
		HIMPP_PRINT("HI_MPI_AF_Register failed [%#x]\n", s32Ret);
		return false;
	}

	return true;
}
bool HimppVideoCodecNVP1918::enableObject()
{
    _codec_fd = open(NVP1918_FILE, O_RDWR);
    if (_codec_fd < 0) {
        HIMPP_PRINT("Open %s failed\n", NVP1918_FILE);
        return false;
    }

    vdec_video_mode vmode = {
        .chip = 0,
        .mode = VDEC_NTSC,
    };
    if (ioctl(_codec_fd, IOC_VDEC_SET_VIDEO_MODE, &vmode)) {
        HIMPP_PRINT("Set nvp1918 video mode failed\n");
        close(_codec_fd);
        return false;
    }

	return true;
}

bool HimppVideoCodecNVP1918::disableObject()
{
	if (_codec_fd != -1)
		close(_codec_fd);

	return true;
}
bool HimppVpssGroup::disableObject()
{
    HI_S32 s32Ret;

    MPP_CHN_S dst_chn;
    dst_chn.enModId = HI_ID_VPSS;
    dst_chn.s32DevId = _grpid;
    dst_chn.s32ChnId = 0;
    if ((s32Ret = HI_MPI_SYS_UnBind(*source(), &dst_chn)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_SYS_UnBind %d failed [%#x]\n",
                    _grpid, s32Ret);
    }

    s32Ret = HI_MPI_VPSS_StopGrp(_grpid);
    if (s32Ret != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VPSS_StopGrp %d failed [%#x]\n",
                    _grpid, s32Ret);
    }

    s32Ret = HI_MPI_VPSS_DestroyGrp(_grpid);
    if (s32Ret != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VPSS_DestroyGrp %d failed [%#x]\n",
                    _grpid, s32Ret);
    }

    return true;
}
bool HimppVpssChan::enableObject()
{
    int grp = _vpss_group->getGroupId();
    int chn = _chnid;
    VPSS_CHN_ATTR_S chn_attr;
    VPSS_CHN_MODE_S chn_mode;
    VPSS_EXT_CHN_ATTR_S ext_chn_attr;
    HI_S32 s32Ret;

    switch (_type) {
    case VPSS_CHN_TYPE_PHY:
        chn_attr.bSpEn = HI_FALSE;
        chn_attr.bBorderEn = HI_FALSE;
        chn_attr.bMirror = HI_FALSE;
        chn_attr.bFlip = HI_FALSE;
        chn_attr.s32SrcFrameRate = -1;
        chn_attr.s32DstFrameRate = -1;
        if ((s32Ret = HI_MPI_VPSS_SetChnAttr(grp, chn, &chn_attr)) != HI_SUCCESS) {
            HIMPP_PRINT("HI_MPI_VPSS_SetChnAttr %d-%d failed %#x\n",
                        grp, chn, s32Ret);
            return false;
        }
        chn_mode.enChnMode = VPSS_CHN_MODE_USER;
        chn_mode.u32Width = _resolution.Width;
        chn_mode.u32Height = _resolution.Height;
        chn_mode.bDouble = HI_FALSE;
        chn_mode.enPixelFormat = HIMPP_PIXEL_FORMAT;
        if ((s32Ret = HI_MPI_VPSS_SetChnMode(grp, chn, &chn_mode)) != HI_SUCCESS) {
            HIMPP_PRINT("HI_MPI_VPSS_SetChnMode %d-%d failed %#x\n",
                        grp, chn, s32Ret);
            return false;
        }
        break;
    case VPSS_CHN_TYPE_EXT:
        ext_chn_attr.s32BindChn = 0;
        ext_chn_attr.s32SrcFrameRate = _framerate;
        if ((s32Ret = HI_MPI_VPSS_SetExtChnAttr(grp, chn, &ext_chn_attr)) != HI_SUCCESS) {
            HIMPP_PRINT("HI_MPI_VPSS_SetExtChnAttr %d-%d failed %#x\n",
                        grp, chn, s32Ret);
            return false;
        }
        break;
    default:
        break;
    }

    if ((s32Ret = HI_MPI_VPSS_EnableChn(grp, chn)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VPSS_EnableChn %d-%d failed [%#x]\n",
                    grp, chn, s32Ret);
        return false;
    }

    return true;
}
bool HimppVpssGroup::enableObject()
{
    HI_S32 s32Ret = HI_FAILURE;

    ImageResolution res = videoSource()->getResolution();
    VPSS_GRP_ATTR_S attr;
    attr.u32MaxW = res.Width;
    attr.u32MaxH = res.Height;
    attr.bDciEn = HI_FALSE;
    attr.bIeEn = HI_FALSE;
    attr.bNrEn = HI_TRUE;
    attr.bHistEn = HI_FALSE;
    attr.enDieMode = VPSS_DIE_MODE_NODIE;
    attr.enPixFmt = HIMPP_PIXEL_FORMAT;
    if ((s32Ret = HI_MPI_VPSS_CreateGrp(_grpid, &attr)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VPSS_CreateGrp %d failed [%#x]\n",
                    _grpid, s32Ret);
        return false;
    }

    if ((s32Ret = HI_MPI_VPSS_StartGrp(_grpid)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VPSS_CreateGrp %d failed [%#x]\n",
                    _grpid, s32Ret);
        goto err_destroy_grp;
    }

    MPP_CHN_S dst_chn;
    dst_chn.enModId = HI_ID_VPSS;
    dst_chn.s32DevId = _grpid;
    dst_chn.s32ChnId = 0;
    if ((s32Ret = HI_MPI_SYS_Bind(*source(), &dst_chn)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_SYS_Bind %d failed [%#x]\n",
                    _grpid, s32Ret);
        goto err_stop_grp;
    }

    return true;

err_stop_grp:
    HI_MPI_VPSS_StopGrp(_grpid);
err_destroy_grp:
    HI_MPI_VPSS_DestroyGrp(_grpid);

    return false;
}
bool HimppVpssChan::disableObject()
{
    int grp = _vpss_group->getGroupId();
    int chn = _chnid;
    HI_S32 s32Ret;

    if ((s32Ret = HI_MPI_VPSS_DisableChn(grp, chn)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VPSS_DisableChn %d-%d failed [%#x]\n",
                    grp, chn, s32Ret);
        return false;
    }

    return true;
}
bool HimppVideoISP::loadSensorModule()
{
	const std::string &path = video_sensor->getModulePath();

	sensor_module.handle = dlopen(path.c_str(), RTLD_LAZY);
	if (sensor_module.handle == NULL) {
		HIMPP_PRINT("Failed to load sensor module '%s'\n", path.c_str());
		return false;
	}

	sensor_module.sensor_init = (SENSOR_INIT_FUNC)dlsym(sensor_module.handle, "sensor_init");
	sensor_module.sensor_register = (SENSOR_REGISTER_FUNC)dlsym(sensor_module.handle, "sensor_register_callback");
	sensor_module.sensor_unregister = (SENSOR_UNREGISTER_FUNC)dlsym(sensor_module.handle, "sensor_unregister_callback");

	if (!sensor_module.sensor_init
		|| !sensor_module.sensor_register
		|| !sensor_module.sensor_unregister) {
		HIMPP_PRINT("Incorrect sensor module.\n");
		goto err_dlclose;
	}

	if (sensor_module.sensor_register() != HI_SUCCESS) {
		HIMPP_PRINT("Failed to register sensor\n");
		goto err_dlclose;
	}

	return true;

err_dlclose:
	dlclose(sensor_module.handle);
	sensor_module.handle = NULL;
	sensor_module.sensor_init = NULL;
	sensor_module.sensor_register = NULL;
	sensor_module.sensor_unregister = NULL;

	return false;
}
bool HimppVencChan::disableObject()
{
    HI_S32 s32Ret;
    GROUP_CROP_CFG_S dis_crop = { .bEnable = HI_FALSE };

    MPP_CHN_S dst_chn = {
        .enModId = HI_ID_GROUP,
        .s32DevId = _grpid,
        .s32ChnId = 0
    };
    if ((s32Ret = HI_MPI_SYS_UnBind(*source(), &dst_chn)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_SYS_UnBind %d failed [%#x]\n",
                    _chnid, s32Ret);
    }

    if ((s32Ret = HI_MPI_VENC_StopRecvPic(_chnid)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_StopRecvPic %d failed [%#x]\n",
                    _chnid, s32Ret);
    }

    if ((s32Ret = HI_MPI_VENC_SetGrpCrop(_grpid, &dis_crop)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_SetGrpCrop [%d] failed [%#x]!\n",
                    _grpid, s32Ret);
    }

    if ((s32Ret = HI_MPI_VENC_UnRegisterChn(_chnid)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_UnRegisterChn %d failed [%#x]\n",
                    _chnid, s32Ret);
    }

    if ((s32Ret = HI_MPI_VENC_DestroyChn(_chnid)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_DestroyChn %d failed [%#x]\n",
                    _chnid, s32Ret);
    }

    if ((s32Ret = HI_MPI_VENC_DestroyGroup(_grpid)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_DestroyGroup %d failed [%#x]\n",
                    _grpid, s32Ret);
    }

    return true;
}
bool HimppVencChan::enableObject()
{
    HI_S32 s32Ret;
    GROUP_CROP_CFG_S dis_crop = { .bEnable = HI_FALSE };

    if ((s32Ret = HI_MPI_VENC_CreateGroup(_grpid)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_CreateGroup %d failed [%#x]\n",
                    _grpid, s32Ret);
        return false;
    }

    VENC_CHN_ATTR_S attr;
    prepareVencChnAttr(attr);
    if ((s32Ret = HI_MPI_VENC_CreateChn(_chnid, &attr)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_CreateChn %d faild [%#x]\n",
                    _chnid, s32Ret);
        goto err_destroy_grp;
    }

    if ((s32Ret = HI_MPI_VENC_SetMaxStreamCnt(_chnid, 4)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_SetMaxStreamCnt %d failed [%#x]\n",
                    _chnid, s32Ret);
    }

    if ((s32Ret = HI_MPI_VENC_RegisterChn(_grpid, _chnid)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_RegisterChn %d-%d failed [%#x]\n",
                    _grpid, _chnid, s32Ret);
        goto err_destroy_chn;
    }

    if ((s32Ret = HI_MPI_VENC_SetGrpCrop(_grpid, &_crop_cfg)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_SetGrpCrop [%d] faild [%#x]!\n",
                    _grpid, s32Ret);
        goto err_unregister_chn;
    }

    if ((s32Ret = HI_MPI_VENC_StartRecvPic(_chnid)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_VENC_StartRecvPic %d failed [%#x]\n",
                    _chnid, s32Ret);
        goto err_disable_crop;
    }

    MPP_CHN_S dst_chn;
    dst_chn.enModId = HI_ID_GROUP;
    dst_chn.s32DevId = _grpid;
    dst_chn.s32ChnId = 0;
    if ((s32Ret = HI_MPI_SYS_Bind(*source(), &dst_chn)) != HI_SUCCESS) {
        HIMPP_PRINT("HI_MPI_SYS_Bind %d failed [%#x]\n",
                    _chnid, s32Ret);
        goto err_stop_recv_pic;
    }

    return true;

err_stop_recv_pic:
    HI_MPI_VENC_StopRecvPic(_chnid);
err_disable_crop:
    HI_MPI_VENC_SetGrpCrop(_grpid, &dis_crop);
err_unregister_chn:
    HI_MPI_VENC_UnRegisterChn(_chnid);
err_destroy_chn:
    HI_MPI_VENC_DestroyChn(_chnid);
err_destroy_grp:
    HI_MPI_VENC_DestroyGroup(_grpid);

    return false;
}
bool HimppVencChan::prepareVencChnAttr(VENC_CHN_ATTR_S &attr)
{
    HI_U32 stattime;
    stattime = _gop / _framerate;
    stattime = stattime > 0 ? stattime : 1;

    switch (_encoding) {
    case H264:
        attr.stVeAttr.enType = PT_H264;
        attr.stVeAttr.stAttrH264e.u32MaxPicWidth = _resolution.Width;
        attr.stVeAttr.stAttrH264e.u32MaxPicHeight = _resolution.Height;
        attr.stVeAttr.stAttrH264e.u32BufSize = _resolution.Width * _resolution.Height * 2;
        attr.stVeAttr.stAttrH264e.u32PicWidth = _resolution.Width;
        attr.stVeAttr.stAttrH264e.u32PicHeight = _resolution.Height;
        attr.stVeAttr.stAttrH264e.u32Profile = _h264profile;
        attr.stVeAttr.stAttrH264e.bByFrame = HI_FALSE;
        attr.stVeAttr.stAttrH264e.bField = HI_FALSE;
        attr.stVeAttr.stAttrH264e.bMainStream = HI_TRUE;
        attr.stVeAttr.stAttrH264e.u32Priority = 0;
        attr.stVeAttr.stAttrH264e.bVIField = HI_FALSE;
        // Rate Control Attribute
        switch (_rcmode) {
        case CBR:
            attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBRv2;
            attr.stRcAttr.stAttrH264Cbr.u32Gop = _gop;
            attr.stRcAttr.stAttrH264Cbr.u32StatTime = stattime;
            attr.stRcAttr.stAttrH264Cbr.u32ViFrmRate = videoSource()->getFramerate();
            attr.stRcAttr.stAttrH264Cbr.fr32TargetFrmRate = _framerate;
            attr.stRcAttr.stAttrH264Cbr.u32BitRate = _bitrate;
            attr.stRcAttr.stAttrH264Cbr.u32FluctuateLevel = 0;
            break;
        case VBR:
            attr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBRv2;
            attr.stRcAttr.stAttrH264Vbr.u32Gop = _gop;
            attr.stRcAttr.stAttrH264Vbr.u32StatTime = stattime;
            attr.stRcAttr.stAttrH264Vbr.u32ViFrmRate = videoSource()->getFramerate();
            attr.stRcAttr.stAttrH264Vbr.fr32TargetFrmRate = _framerate;
            attr.stRcAttr.stAttrH264Vbr.u32MinQp = 24;
            attr.stRcAttr.stAttrH264Vbr.u32MaxQp = 45;
            attr.stRcAttr.stAttrH264Vbr.u32MaxBitRate = _bitrate;
            break;
        case FIXQP:
            attr.stRcAttr.enRcMode = VENC_RC_MODE_H264FIXQP;
            attr.stRcAttr.stAttrH264FixQp.u32Gop = _gop;
            attr.stRcAttr.stAttrH264FixQp.u32ViFrmRate = videoSource()->getFramerate();
            attr.stRcAttr.stAttrH264FixQp.fr32TargetFrmRate = _framerate;
            attr.stRcAttr.stAttrH264FixQp.u32IQp = 20;
            attr.stRcAttr.stAttrH264FixQp.u32PQp = 23;
            break;
        default:
            HIMPP_PRINT("Unsupported RC mode[%d]\n", _rcmode);
            return false;
        }
        break;
    case MJPEG:
        attr.stVeAttr.enType = PT_MJPEG;
        attr.stVeAttr.stAttrMjpeg.u32MaxPicWidth = _resolution.Width;
        attr.stVeAttr.stAttrMjpeg.u32MaxPicHeight = _resolution.Height;
        attr.stVeAttr.stAttrMjpeg.u32BufSize = _resolution.Width * _resolution.Height * 2;
        attr.stVeAttr.stAttrMjpeg.u32PicWidth = _resolution.Width;
        attr.stVeAttr.stAttrMjpeg.u32PicHeight = _resolution.Height;
        attr.stVeAttr.stAttrMjpeg.bByFrame = HI_TRUE;
        attr.stVeAttr.stAttrMjpeg.bVIField = HI_FALSE;
        attr.stVeAttr.stAttrMjpeg.bMainStream = HI_TRUE;
        attr.stVeAttr.stAttrMjpeg.u32Priority = 0;
        // Rate Control Attribute
        switch (_rcmode) {
        case CBR:
            attr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGCBR;
            attr.stRcAttr.stAttrMjpegeCbr.u32StatTime = 1;
            attr.stRcAttr.stAttrMjpegeCbr.u32ViFrmRate = videoSource()->getFramerate();
            attr.stRcAttr.stAttrMjpegeCbr.fr32TargetFrmRate = _framerate;
            attr.stRcAttr.stAttrMjpegeCbr.u32BitRate = _bitrate;
            attr.stRcAttr.stAttrMjpegeCbr.u32FluctuateLevel = 0;
            break;
        case VBR:
            attr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGVBR;
            attr.stRcAttr.stAttrMjpegeVbr.u32StatTime = 1;
            attr.stRcAttr.stAttrMjpegeVbr.u32ViFrmRate = videoSource()->getFramerate();
            attr.stRcAttr.stAttrMjpegeVbr.fr32TargetFrmRate = _framerate;
            attr.stRcAttr.stAttrMjpegeVbr.u32MinQfactor = 50;
            attr.stRcAttr.stAttrMjpegeVbr.u32MaxQfactor = 95;
            break;
        case FIXQP:
            attr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGFIXQP;
            attr.stRcAttr.stAttrMjpegeFixQp.u32ViFrmRate = videoSource()->getFramerate();
            attr.stRcAttr.stAttrMjpegeFixQp.fr32TargetFrmRate = _framerate;
            attr.stRcAttr.stAttrMjpegeFixQp.u32Qfactor = 90;
            break;
        default:
            HIMPP_PRINT("Unsupported RC mode[%d]\n", _rcmode);
            return false;
        }
        break;
    case JPEG:
        attr.stVeAttr.enType = PT_JPEG;
        attr.stVeAttr.stAttrJpeg.u32PicWidth = _resolution.Width;
        attr.stVeAttr.stAttrJpeg.u32PicHeight = _resolution.Height;
        attr.stVeAttr.stAttrJpeg.u32BufSize = _resolution.Width * _resolution.Height * 2;
        attr.stVeAttr.stAttrJpeg.bByFrame = HI_TRUE;
        attr.stVeAttr.stAttrJpeg.bVIField = HI_FALSE;
        attr.stVeAttr.stAttrJpeg.u32Priority = 0;
        break;
    default:
        HIMPP_PRINT("Unsupported encoding code[%d]\n", _encoding);
        return false;
    }
    return true;
}