/*
 * STDC inference application for KL630 host_stream
 * Follows demo_customize_inf_single_model.c pattern
 */

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "vmf_nnm_inference_app.h"
#include "vmf_nnm_fifoq_manager.h"
#include "stdc_app.h"
#include "stdc_post_process.h"

void stdc_inference(int job_id, int num_input_buf, void **inf_input_buf_list)
{
    if (1 != num_input_buf) {
        VMF_NNM_Fifoq_Manager_Status_Code_Enqueue(job_id, KP_FW_WRONG_INPUT_BUFFER_COUNT_110);
        return;
    }

    int result_buf_size;
    uint32_t inf_result_buf;
    uint32_t inf_result_phy_addr;

    if (KP_SUCCESS != VMF_NNM_Fifoq_Manager_Result_Get_Free_Buffer(
            &inf_result_buf, &inf_result_phy_addr, &result_buf_size, -1)) {
        printf("[%s] get result free buffer failed\n", __FUNCTION__);
        return;
    }

    stdc_inf_header_t  *input_header  = (stdc_inf_header_t  *)inf_input_buf_list[0];
    stdc_inf_result_t  *output_result = (stdc_inf_result_t  *)inf_result_buf;
    stdc_post_proc_params_t post_proc_params;

    /* Configure inference */
    VMF_NNM_INFERENCE_APP_CONFIG_T inf_config;
    memset(&inf_config, 0, sizeof(VMF_NNM_INFERENCE_APP_CONFIG_T));

    inf_config.num_image = 1;

    /* Image data immediately follows the header in the input buffer */
    inf_config.image_list[0].image_buf     = (void *)((uint32_t)input_header + sizeof(stdc_inf_header_t));
    inf_config.image_list[0].image_width   = input_header->width;
    inf_config.image_list[0].image_height  = input_header->height;
    inf_config.image_list[0].image_channel = 3;
    inf_config.image_list[0].image_format  = KP_IMAGE_FORMAT_YUV420;  /* ISP output format */
    inf_config.image_list[0].image_norm    = KP_NORMALIZE_KNERON;     /* matches Python: /256 - 0.5 */
    inf_config.image_list[0].image_resize  = KP_RESIZE_ENABLE;
    inf_config.image_list[0].image_padding = KP_PADDING_CORNER;

    post_proc_params.fps        = (input_header->fps > 0.0f) ? input_header->fps : 1.0f;
    inf_config.model_id         = input_header->model_id ? input_header->model_id : STDC_MODEL_ID;
    inf_config.ncpu_result_buf  = (void *)&output_result->stdc_result;
    inf_config.user_define_data = (void *)&post_proc_params;
    inf_config.post_proc_func   = stdc_post_process;

    int inf_status = VMF_NNM_Inference_App_Execute(&inf_config);

    output_result->header_stamp.magic_type  = KDP2_MAGIC_TYPE_INFERENCE;
    output_result->header_stamp.total_size  = sizeof(stdc_inf_result_t);
    output_result->header_stamp.job_id      = job_id;
    output_result->header_stamp.status_code = inf_status;

    VMF_NNM_Fifoq_Manager_Result_Enqueue(
        inf_result_buf, inf_result_phy_addr, result_buf_size, -1, false);
}

void stdc_inference_deinit(void)
{
    /* No temporary buffers to release */
}
