/******************************************************************************\ |* Copyright (c) 2017-2021 by Vivante Corporation. All Rights Reserved. *| |* *| |* The material in this file is confidential and contains trade secrets of *| |* of Vivante Corporation. This is proprietary information owned by Vivante *| |* Corporation. No part of this work may be disclosed, reproduced, copied, *| |* transmitted, or used in any way for any purpose, without the express *| |* written permission of Vivante Corporation. *| |* *| \******************************************************************************/ #include "tim/utils/nbg_parser/nbg_parser.h" #include "tim/utils/nbg_parser/nbg_parser_impl.h" #include "tim/utils/nbg_parser/nbg_parser_version.h" #include #include #include /* Some functions, depends on runtime system, need to be modified on RTOS or DSP */ #define nbg_printf printf #define goOnError(func) \ status = func; \ goto onError; static const vip_char_t* dummy_name = "dummy_name"; static void* nbg_malloc(vip_uint32_t size) { return malloc(size); } static nbg_status_e nbg_free(void *data) { free(data); return NBG_SUCCESS; } static void* nbg_memcpy(void *dst, const void *src, vip_uint32_t size) { return memcpy(dst, src, size); } static void* nbg_memset(void *dst, vip_uint32_t size) { return memset(dst, 0, size); } static nbg_uint32_t nbg_strlen(const nbg_char_t *str) { return strlen(str); } static nbg_char_t* nbg_strcpy(nbg_char_t *dst, const nbg_char_t *src) { strcpy(dst, src); return dst; } /*********************** NBG parser internal functions ***********/ #define OLD_NBG_FORMAT_DIMS_NUM 4 static vip_int8_t read_byte(nbg_reader_t *reader) { vip_int8_t data = 0; if (reader->offset <= reader->total_size) { data = *((vip_int8_t *)reader->current_data); reader->offset += sizeof(vip_int8_t); reader->current_data += sizeof(vip_int8_t); } else { nbg_printf("fail to read nbg data, out of buffer, offset=%d, total size=%d\n", reader->offset, reader->total_size); } return data; } static vip_uint32_t read_uInt(nbg_reader_t *reader) { vip_uint32_t data = 0; if (reader->offset <= reader->total_size) { data = *((vip_uint32_t *)reader->current_data); reader->offset += sizeof(vip_uint32_t); reader->current_data += sizeof(vip_uint32_t); } else { nbg_printf("fail to read nbg data, out of buffer, offset=%d, total size=%d\n", reader->offset, reader->total_size); } return data; } static nbg_status_e read_data(nbg_reader_t *reader, void *dst, vip_uint32_t size) { nbg_status_e status = NBG_SUCCESS; if (reader->offset <= reader->total_size) { nbg_memcpy(dst, reader->current_data, size); reader->offset += size; reader->current_data += size; } else { nbg_printf("fail to read nbg data, out of buffer, offset=%d, total size=%d\n", reader->offset, reader->total_size); status = NBG_ERROR_FAILURE; } return status; } static nbg_status_e reader_locate( nbg_reader_t *reader, vip_uint32_t location ) { nbg_status_e status = NBG_SUCCESS; if (location > reader->total_size) { nbg_printf("failed to locate nbg buffer, Location > reader->size\n"); status = NBG_ERROR_INVALID_ARGUMENTS; } else { reader->offset = location; reader->current_data = reader->data + reader->offset; } return status; } static nbg_status_e read_bin_header(nbg_reader_t *reader, gcvip_bin_header_t *header) { nbg_status_e status = NBG_SUCCESS; vip_uint32_t i = 0; static const vip_char_t magic[4] = {'V', 'P', 'M', 'N'}; /* Read magic. */ for (i = 0; i < 4; i++) { header->magic[i] = read_byte(reader); if (header->magic[i] != magic[i]) { nbg_printf("binary magic not match\n"); goOnError(NBG_ERROR_FAILURE); } } /* Read "Version". */ header->version = read_uInt(reader); if (header->version > NBG_FORMAT_VERSION) { nbg_printf("NBG parser is forward compatible with NBG format, " "please update NBG parser in time\n"); goOnError(NBG_ERROR_FAILURE); } /* Read "hardware target". */ header->hw_target = read_uInt(reader); /* Read "network_name". */ read_data(reader, header->network_name, sizeof(header->network_name)); /* Read "Layer_count". */ header->layer_count = read_uInt(reader); /* Read "operation_count". */ header->operation_count = read_uInt(reader); /* Read "input_count". */ header->input_count = read_uInt(reader); /* Read "output_count". */ header->output_count = read_uInt(reader); if (header->version >= 0x00010003) { read_data(reader, &header->feature_db, sizeof(gcvip_bin_feature_database_t)); } onError: return status; } static nbg_status_e read_bin_entry(nbg_reader_t *reader, gcvip_bin_entry_t *entry ) { nbg_status_e status = NBG_SUCCESS; entry->offset = read_uInt(reader); entry->size = read_uInt(reader); return status; } static nbg_status_e read_nbg_dyn_data(nbg_parser_data_t *nbg) { nbg_status_e status = NBG_SUCCESS; nbg_reader_t *reader = &nbg->reader; /* read input data */ if (nbg->fixed.input_table.size > 0) { nbg->inputs = (gcvip_bin_inout_entry_t*)nbg_malloc(nbg->fixed.input_table.size); if (nbg->inputs == NBG_NULL) { nbg_printf("failed to malloc memory for inputs\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->inputs, nbg->fixed.input_table.size); reader_locate(reader, nbg->fixed.input_table.offset); read_data(reader, nbg->inputs, nbg->fixed.input_table.size); if (nbg->fixed.header.version >= 0x0001000B) { nbg->n_inputs = nbg->fixed.input_table.size / sizeof(gcvip_bin_inout_entry_t); } else if ((nbg->fixed.header.version >= 0x00010004) && (nbg->fixed.header.version < 0x0001000B)) { nbg_uint32_t size = 0; size = sizeof(gcvip_bin_inout_entry_t) - (MAX_NUM_DIMS - OLD_NBG_FORMAT_DIMS_NUM) * sizeof(nbg_uint32_t); nbg->n_inputs = nbg->fixed.input_table.size / size; } else { nbg_uint32_t size = 0; size = (sizeof(gcvip_bin_inout_entry_t) - sizeof(vip_char_t) * MAX_IO_NAME_LEGTH - (MAX_NUM_DIMS - OLD_NBG_FORMAT_DIMS_NUM) * sizeof(nbg_uint32_t)); nbg->n_inputs = nbg->fixed.input_table.size / size; } } /* read output data */ if (nbg->fixed.output_table.size > 0) { nbg->outputs = (gcvip_bin_inout_entry_t*)nbg_malloc(nbg->fixed.output_table.size); if (nbg->outputs == NBG_NULL) { nbg_printf("failed to malloc memory for outputs\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->outputs, nbg->fixed.output_table.size); reader_locate(reader, nbg->fixed.output_table.offset); read_data(reader, nbg->outputs, nbg->fixed.output_table.size); if (nbg->fixed.header.version >= 0x0001000B) { nbg->n_outputs = nbg->fixed.output_table.size / sizeof(gcvip_bin_inout_entry_t); } else if ((nbg->fixed.header.version >= 0x00010004) && (nbg->fixed.header.version < 0x0001000B)) { nbg_uint32_t size = 0; size = sizeof(gcvip_bin_inout_entry_t) - (MAX_NUM_DIMS - OLD_NBG_FORMAT_DIMS_NUM) * sizeof(nbg_uint32_t); nbg->n_outputs = nbg->fixed.output_table.size / size; } else { nbg_uint32_t size = 0; size = sizeof(gcvip_bin_inout_entry_t) - sizeof(vip_char_t) * MAX_IO_NAME_LEGTH - (MAX_NUM_DIMS - OLD_NBG_FORMAT_DIMS_NUM) * sizeof(nbg_uint32_t); nbg->n_outputs = nbg->fixed.output_table.size / size; } } /* read layer data */ if (nbg->fixed.layer_table.size > 0) { nbg->orig_layers = (gcvip_bin_layer_t*)nbg_malloc(nbg->fixed.layer_table.size); if (nbg->orig_layers == NBG_NULL) { nbg_printf("failed to malloc memory for layer data\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->orig_layers, nbg->fixed.layer_table.size); reader_locate(reader, nbg->fixed.layer_table.offset); read_data(reader, nbg->orig_layers, nbg->fixed.layer_table.size); if (nbg->fixed.header.version >= 0x00010008) { nbg->n_orig_layers = nbg->fixed.layer_table.size / sizeof(gcvip_bin_layer_t); } else { nbg->n_orig_layers = nbg->fixed.layer_table.size / (sizeof(gcvip_bin_layer_t) - sizeof(vip_uint32_t)); } } /* read operation data */ if (nbg->fixed.opeartion_table.size > 0) { nbg->operations = (gcvip_bin_operation_t*)nbg_malloc(nbg->fixed.opeartion_table.size); if (nbg->operations == NBG_NULL) { nbg_printf("failed to malloc memory for operation data\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->operations, nbg->fixed.opeartion_table.size); reader_locate(reader, nbg->fixed.opeartion_table.offset); read_data(reader, nbg->operations, nbg->fixed.opeartion_table.size); nbg->n_operations = nbg->fixed.opeartion_table.size / sizeof(gcvip_bin_operation_t); } /* read nn operation */ if (nbg->fixed.nn_op_data_table.size > 0) { nbg->nn_ops = (void*)nbg_malloc(nbg->fixed.nn_op_data_table.size); if (nbg->nn_ops == NBG_NULL) { nbg_printf("failed to malloc memory for nn operation data\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->nn_ops, nbg->fixed.nn_op_data_table.size); reader_locate(reader, nbg->fixed.nn_op_data_table.offset); read_data(reader, nbg->nn_ops, nbg->fixed.nn_op_data_table.size); if (NBG_NN_COMMAND_SIZE_192 == nbg->fixed.header.feature_db.nn_command_size) { nbg->n_nn_ops = nbg->fixed.nn_op_data_table.size / sizeof(gcvip_bin_nn_operation_192bytes_t); } else { nbg->n_nn_ops = nbg->fixed.nn_op_data_table.size / sizeof(gcvip_bin_nn_operation_t); } } /* read TP opeartion */ if (nbg->fixed.tp_op_data_table.size > 0) { nbg->tp_ops = (void*)nbg_malloc(nbg->fixed.tp_op_data_table.size); if (nbg->tp_ops == NBG_NULL) { nbg_printf("failed to malloc memory for tp operation data\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->tp_ops, nbg->fixed.tp_op_data_table.size); reader_locate(reader, nbg->fixed.tp_op_data_table.offset); read_data(reader, nbg->tp_ops, nbg->fixed.tp_op_data_table.size); nbg->n_tp_ops = nbg->fixed.tp_op_data_table.size / sizeof(gcvip_bin_tp_operation_t); } /* read shader opeartion */ if (nbg->fixed.sh_op_data_table.size > 0) { nbg->sh_ops = (gcvip_bin_sh_operation_t*)nbg_malloc(nbg->fixed.sh_op_data_table.size); if (nbg->sh_ops == NBG_NULL) { nbg_printf("failed to malloc memory for shader operation data\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->sh_ops, nbg->fixed.sh_op_data_table.size); reader_locate(reader, nbg->fixed.sh_op_data_table.offset); read_data(reader, nbg->sh_ops, nbg->fixed.sh_op_data_table.size); if (nbg->fixed.header.version >= 0x0001000E) { nbg->n_sh_ops = nbg->fixed.sh_op_data_table.size / sizeof(gcvip_bin_sh_operation_t); } else { nbg->n_sh_ops = nbg->fixed.sh_op_data_table.size / (sizeof(gcvip_bin_sh_operation_t) - sizeof(vip_uint32_t)); } } /* read patch data */ if (nbg->fixed.patch_data_table.size > 0) { nbg->pd_entries = (gcvip_bin_patch_data_entry_t*)nbg_malloc(nbg->fixed.patch_data_table.size); if (nbg->pd_entries == NBG_NULL) { nbg_printf("failed to malloc memory for patch data data\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->pd_entries, nbg->fixed.patch_data_table.size); reader_locate(reader, nbg->fixed.patch_data_table.offset); read_data(reader, nbg->pd_entries, nbg->fixed.patch_data_table.size); nbg->n_pd_entries = nbg->fixed.patch_data_table.size / sizeof(gcvip_bin_patch_data_entry_t); } /* read lcd table */ if (nbg->fixed.LCD_table.size > 0) { nbg->LCDT = (gcvip_bin_entry_t*)nbg_malloc(nbg->fixed.LCD_table.size); if (nbg->LCDT == NBG_NULL) { nbg_printf("failed to malloc memory for lcd table data\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->LCDT, nbg->fixed.LCD_table.size); reader_locate(reader, nbg->fixed.LCD_table.offset); read_data(reader, nbg->LCDT, nbg->fixed.LCD_table.size); nbg->n_LCDT = nbg->fixed.LCD_table.size / sizeof(gcvip_bin_entry_t); } /* read hw init operation table */ if (nbg->fixed.hw_init_op_table.size > 0) { nbg->hw_init_ops = (gcvip_bin_hw_init_operation_info_entry_t*)nbg_malloc(nbg->fixed.hw_init_op_table.size); if (nbg->hw_init_ops == NBG_NULL) { nbg_printf("failed to malloc memory for hardware initialize operations\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->hw_init_ops, nbg->fixed.hw_init_op_table.size); reader_locate(reader, nbg->fixed.hw_init_op_table.offset); read_data(reader, nbg->hw_init_ops, nbg->fixed.hw_init_op_table.size); nbg->n_hw_init_ops = nbg->fixed.hw_init_op_table.size / sizeof(gcvip_bin_hw_init_operation_info_entry_t); } /* read ICD table */ if (nbg->fixed.ICD_table.size > 0) { nbg->ICDT = (gcvip_bin_entry_t*)nbg_malloc(nbg->fixed.ICD_table.size); if (nbg->ICDT == NBG_NULL) { nbg_printf("failed to malloc memory for ICDT\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->ICDT, nbg->fixed.ICD_table.size); reader_locate(reader, nbg->fixed.ICD_table.offset); read_data(reader, nbg->ICDT, nbg->fixed.ICD_table.size); nbg->n_ICDT = nbg->fixed.ICD_table.size / sizeof(gcvip_bin_entry_t); } /* read LCD */ if (nbg->fixed.LCD.size > 0) { nbg->LCD = (void*)nbg_malloc(nbg->fixed.LCD.size); if (nbg->LCD == NBG_NULL) { nbg_printf("failed to malloc memory for LCD operation data\n"); goOnError(NBG_ERROR_FAILURE); } nbg_memset(nbg->LCD, nbg->fixed.LCD.size); reader_locate(reader, nbg->fixed.LCD.offset); read_data(reader, nbg->LCD, nbg->fixed.LCD.size); } return status; onError: if (nbg->inputs != NBG_NULL) { nbg_free(nbg->inputs); nbg->inputs = NBG_NULL; } if (nbg->outputs != NBG_NULL) { nbg_free(nbg->outputs); nbg->outputs = NBG_NULL; } if (nbg->orig_layers != NBG_NULL) { nbg_free(nbg->orig_layers); nbg->orig_layers = NBG_NULL; } if (nbg->operations != NBG_NULL) { nbg_free(nbg->operations); nbg->operations = NBG_NULL; } if (nbg->LCDT != NBG_NULL) { nbg_free(nbg->LCDT); nbg->LCDT = NBG_NULL; } if (nbg->pd_entries != NBG_NULL) { nbg_free(nbg->pd_entries); nbg->pd_entries = NBG_NULL; } if (nbg->sh_ops != NBG_NULL) { nbg_free(nbg->sh_ops); nbg->sh_ops = NBG_NULL; } if (nbg->hw_init_ops != NBG_NULL) { nbg_free(nbg->hw_init_ops); nbg->hw_init_ops = NBG_NULL; } if (nbg->ICDT != NBG_NULL) { nbg_free(nbg->ICDT); nbg->ICDT = NBG_NULL; } if (nbg->nn_ops != NBG_NULL) { nbg_free(nbg->nn_ops); nbg->nn_ops = NBG_NULL; } if (nbg->tp_ops != NBG_NULL) { nbg_free(nbg->tp_ops); nbg->tp_ops = NBG_NULL; } if (nbg->LCD != NBG_NULL) { nbg_free(nbg->LCD); nbg->LCD = NBG_NULL; } return status; } static nbg_status_e read_nbg_fix_data(nbg_parser_data_t *nbg) { nbg_status_e status = NBG_SUCCESS; nbg_reader_t *reader = &nbg->reader; status = read_bin_header(reader, &nbg->fixed.header); if (status != NBG_SUCCESS) { nbg_printf("fail to read NBG header\n"); goOnError(status); } /* read memory pool */ nbg->fixed.pool.size = read_uInt(reader); nbg->fixed.pool.alignment = read_uInt(reader); nbg->fixed.pool.base = read_uInt(reader); /* read sram */ nbg->fixed.axi_sram_base = read_uInt(reader); nbg->fixed.axi_sram_size = read_uInt(reader); if (nbg->fixed.header.version >= 0x00010008) { nbg->fixed.vip_sram_base = read_uInt(reader); nbg->fixed.vip_sram_size = read_uInt(reader); } /* read entry */ read_bin_entry(reader, &nbg->fixed.input_table); read_bin_entry(reader, &nbg->fixed.output_table); read_bin_entry(reader, &nbg->fixed.layer_table); read_bin_entry(reader, &nbg->fixed.opeartion_table); read_bin_entry(reader, &nbg->fixed.LCD_table); read_bin_entry(reader, &nbg->fixed.LCD); read_bin_entry(reader, &nbg->fixed.nn_op_data_table); read_bin_entry(reader, &nbg->fixed.tp_op_data_table); read_bin_entry(reader, &nbg->fixed.sh_op_data_table); read_bin_entry(reader, &nbg->fixed.patch_data_table); read_bin_entry(reader, &nbg->fixed.layer_param_table); read_bin_entry(reader, &nbg->fixed.sw_op_data_table); if (nbg->fixed.header.version >= 0x0001000C) { read_bin_entry(reader, &nbg->fixed.hw_init_op_table); read_bin_entry(reader, &nbg->fixed.ICD_table); read_bin_entry(reader, &nbg->fixed.ICD); } else { nbg->fixed.hw_init_op_table.size = 0; nbg->fixed.ICD_table.size = 0; nbg->fixed.ICD.size = 0; } if (nbg->fixed.header.version >= 0x0001000E) { read_bin_entry(reader, &nbg->fixed.ppu_param_table); } else { nbg->fixed.ppu_param_table.size = 0; } onError: return status; } static void *get_io_ptr_by_index( nbg_parser_data_t *nbg, gcvip_bin_inout_entry_t *io_ptr, vip_int32_t index ) { void *ptr_io = NBG_NULL; vip_uint32_t size_04 = 0, size_0B = 0; size_04 = sizeof(gcvip_bin_inout_entry_t) - sizeof(vip_int8_t) * MAX_IO_NAME_LEGTH - sizeof (vip_uint32_t) * (MAX_NUM_DIMS - OLD_NBG_FORMAT_DIMS_NUM); size_0B = sizeof(gcvip_bin_inout_entry_t) - sizeof (vip_uint32_t) * (MAX_NUM_DIMS - OLD_NBG_FORMAT_DIMS_NUM); if (nbg->fixed.header.version >= 0x0001000B) { ptr_io = (void *)(io_ptr + index); } else if ((nbg->fixed.header.version >= 0x00010004) && (nbg->fixed.header.version < 0x0001000B)) { ptr_io = (void *)((vip_int8_t *)io_ptr + index * size_0B); } else { ptr_io = (void *)((vip_int8_t *)io_ptr + index * size_04); } return ptr_io; } static nbg_status_e query_input_output( nbg_parser_data nbg, void *entry, vip_uint32_t property, void *value, nbg_uint32_t size ) { nbg_status_e status = NBG_SUCCESS; nbg_parser_data_t *nbg_data = (nbg_parser_data_t*)nbg; vip_uint32_t *ptr_u32 = (vip_uint32_t *)value; vip_int32_t *ptr_32 = (vip_int32_t *)value; vip_float_t *ptr_fl = (vip_float_t *)value; vip_char_t *ptr_char = (vip_char_t *)value; vip_uint32_t i = 0; if (NBG_NULL == entry) { nbg_printf("buffer entry is NULL\n"); goOnError(NBG_ERROR_FAILURE); } if (nbg_data->fixed.header.version >= 0x0001000B) { gcvip_bin_inout_entry_t *inout_entry = (gcvip_bin_inout_entry_t*)entry; switch (property) { case NBG_PARSER_BUFFER_PROP_QUANT_FORMAT: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->quan_format; } else { nbg_printf("failed to query quan format, value is a uint32 buffer and size is 4byte\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_NUM_OF_DIMENSION: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->dim_count; } else { nbg_printf("failed to query dims count, value is a uint32 buffer and size is 4byte\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_DIMENSIONS: if (size >= (sizeof(vip_uint32_t) * inout_entry->dim_count)) { for (i = 0; i < inout_entry->dim_count; i++) { ptr_u32[i] = inout_entry->dim_size[i]; } } else { nbg_printf("failed to query dims, value is 4 uint32 buffer and size is 16byte\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_DATA_FORMAT: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->data_format; } else { nbg_printf("failed to query data format, value is a uint32 buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_DATA_TYPE: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->data_type; } else { nbg_printf("failed to query data type, value is a uint32 buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_FIXED_POINT_POS: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->fixed_pos; } else { nbg_printf("failed to query fixed point pos, value is a uint32 buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_SCALE: if (size >= sizeof(vip_float_t)) { *ptr_fl = inout_entry->tf_scale; } else { nbg_printf("failed to query scale, value is a float buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_ZERO_POINT: if (size >= sizeof(vip_uint32_t)) { *ptr_32 = inout_entry->tf_zerop; } else { nbg_printf("failed to query zero point, value is a uint32 buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_NAME: { nbg_uint32_t len = nbg_strlen(inout_entry->name) + 1; if (size >= len) { nbg_strcpy(ptr_char, inout_entry->name); } else { nbg_printf("failed to query name, value size is %d\n\n", len); goOnError(NBG_ERROR_FAILURE); } } break; case NBG_PARSER_BUFFER_PROP_NAME_SIZE: { nbg_uint32_t len = nbg_strlen(inout_entry->name) + 1; if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = len; } else { nbg_printf("failed to query name size, value size if uint32 dat type\n"); goOnError(NBG_ERROR_FAILURE); } } break; default: nbg_printf("NBG doesn't support this property=%d\n", property); status = NBG_ERROR_INVALID_ARGUMENTS; break; } } else { typedef struct _gcvip_bin_inout_entry_old { vip_uint32_t dim_count; vip_uint32_t dim_size[4]; vip_uint32_t data_format; vip_uint32_t data_type; vip_uint32_t quan_format; vip_uint32_t fixed_pos; vip_float_t tf_scale; vip_uint32_t tf_zerop; vip_char_t name[MAX_IO_NAME_LEGTH]; } gcvip_bin_inout_entry_old_t; gcvip_bin_inout_entry_old_t *inout_entry = (gcvip_bin_inout_entry_old_t*)entry; switch (property) { case NBG_PARSER_BUFFER_PROP_QUANT_FORMAT: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->quan_format; } else { nbg_printf("failed to query quan format, value is a uint32 buffer and size is 4byte\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_NUM_OF_DIMENSION: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->dim_count; } else { nbg_printf("failed to query dims count, value is a uint32 buffer and size is 4byte\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_DIMENSIONS: if (size >= (sizeof(vip_uint32_t) * inout_entry->dim_count)) { for (i = 0; i < inout_entry->dim_count; i++) { ptr_u32[i] = inout_entry->dim_size[i]; } } else { nbg_printf("failed to query dims, value is 4 uint32 buffer and size is 16byte\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_DATA_FORMAT: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->data_format; } else { nbg_printf("failed to query data format, value is a uint32 buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_DATA_TYPE: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->data_type; } else { nbg_printf("failed to query data type, value is a uint32 buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_FIXED_POINT_POS: if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = inout_entry->fixed_pos; } else { nbg_printf("failed to query fixed point pos, value is a uint32 buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_SCALE: if (size >= sizeof(vip_float_t)) { *ptr_fl = inout_entry->tf_scale; } else { nbg_printf("failed to query scale, value is a float buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_ZERO_POINT: if (size >= sizeof(vip_uint32_t)) { *ptr_32 = inout_entry->tf_zerop; } else { nbg_printf("failed to query zero point, value is a uint32 buffer and size is 4byte\n\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_BUFFER_PROP_NAME: { nbg_uint32_t len = nbg_strlen(inout_entry->name) + 1; if (nbg_data->fixed.header.version >= 0x00010004) { if (size >= len) { nbg_strcpy(ptr_char, inout_entry->name); } else { nbg_printf("failed to query name, value size is %d\n\n", len); goOnError(NBG_ERROR_FAILURE); } } else { nbg_strcpy(ptr_char, dummy_name); } } break; case NBG_PARSER_BUFFER_PROP_NAME_SIZE: { if (nbg_data->fixed.header.version < 0x00010004) { *ptr_u32 = nbg_strlen(dummy_name) + 1; } else { nbg_uint32_t len = nbg_strlen(inout_entry->name) + 1; if (size >= sizeof(vip_uint32_t)) { *ptr_u32 = len; } else { nbg_printf("failed to query name size, value size if uint32 dat type\n"); goOnError(NBG_ERROR_FAILURE); } } } break; default: nbg_printf("NBG doesn't support this property=%d\n", property); status = NBG_ERROR_INVALID_ARGUMENTS; break; } } onError: return status; } /*********************** expose APIs ****************************/ /* @brief, Query NBG parser library version */ nbg_uint32_t nbg_parser_version(void) { nbg_uint32_t version = (VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_SUB_MINOR); return version; } /* @brief, Initialize NBG parser. @param, buffer. a pointer to the start of the NBG data @param size, the size of NBG data. @param, nbg_t*, the nbg object created by NBG data. */ nbg_status_e nbg_parser_init(void *buffer, nbg_uint32_t size, nbg_parser_data *nbg) { nbg_parser_data_t *nbg_data = NBG_NULL; nbg_status_e status = NBG_SUCCESS; nbg_data = (nbg_parser_data_t *)nbg_malloc(sizeof(nbg_parser_data_t)); if (nbg_data != NBG_NULL) { nbg_memset(nbg_data, sizeof(nbg_parser_data_t)); nbg_data->reader.current_data = (vip_uint8_t*)buffer; nbg_data->reader.data = (vip_uint8_t*)buffer; nbg_data->reader.total_size = size; nbg_data->reader.offset = 0; status = read_nbg_fix_data(nbg_data); if (status != NBG_SUCCESS) { nbg_printf("failed to read fix section data\n"); goOnError(status); } status = read_nbg_dyn_data(nbg_data); if (status != NBG_SUCCESS) { nbg_printf("failed to read dynmic section data\n"); goOnError(status); } } else { nbg_printf("failed to malloc memory for nbg object\n"); goOnError(status); } if (nbg != NBG_NULL) { *nbg = (nbg_parser_data)nbg_data; } onError: return status; } /* @brief, query the input info of network. @param nbg, The nbg object created by NBG data. @param index, The index of input. @param property, The property of input. Quant format, dimension count, shape, data format and so on. see nbg_buffer_property_e enumeration. @param size, the size of value buffer. @param, return value. */ nbg_status_e nbg_parser_query_input( nbg_parser_data nbg, vip_uint32_t index, vip_uint32_t property, void *value, nbg_uint32_t size ) { nbg_status_e status = NBG_SUCCESS; gcvip_bin_inout_entry_t *input; nbg_parser_data_t *nbg_data = (nbg_parser_data_t*)nbg; if ((nbg_data == NBG_NULL) || (value == NBG_NULL) || (0 == size)) { nbg_printf("failed to query input, parameter is NULL, nbg=%p, " "index=%d, property=%d, value=%p, size=%d\n", nbg, index, property, value, size); return NBG_ERROR_FAILURE; } input = (gcvip_bin_inout_entry_t *)get_io_ptr_by_index(nbg_data, nbg_data->inputs, index); status = query_input_output(nbg, input, property, value, size); if (status != NBG_SUCCESS) { nbg_printf("failed to query input buffer information\n"); } return status; } /* @brief, query the output info of network. @param nbg, The nbg object created by NBG data. @param index, The nbg object created by NBG data. @param property, The property of input. Quant format, dimension count, shape, data format and so on. see nbg_buffer_property_e enumeration. @param size, The size of value buffer. @param, return value. */ nbg_status_e nbg_parser_query_output( nbg_parser_data nbg, vip_uint32_t index, vip_uint32_t property, void *value, nbg_uint32_t size ) { nbg_status_e status = NBG_SUCCESS; gcvip_bin_inout_entry_t *output; nbg_parser_data_t *nbg_data = (nbg_parser_data_t*)nbg; if ((nbg_data == NBG_NULL) || (value == NBG_NULL) || (0 == size)) { nbg_printf("failed to query output, parameter is NULL, nbg=%p, index=%d, " "property=%d, value=%p, size=%d\n", nbg, index, property, value, size); return NBG_ERROR_FAILURE; } output = (gcvip_bin_inout_entry_t *)get_io_ptr_by_index(nbg_data, nbg_data->outputs, index); status = query_input_output(nbg, output, property, value, size); if (status != NBG_SUCCESS) { nbg_printf("failed to query input buffer information\n"); } return status; } /* @brief, query the network info. @param property, The property of the network is queried. network name, input count, output count and so on. see nbg_network_propery_e enumeration. @param size, the size of value buffer. @param value, return value. */ nbg_status_e nbg_parser_query_network( nbg_parser_data nbg, vip_uint32_t property, void *value, nbg_uint32_t size ) { nbg_status_e status = NBG_SUCCESS; nbg_parser_data_t *nbg_data = (nbg_parser_data_t*)nbg; if ((nbg_data == NBG_NULL) || (value == NBG_NULL) || (0 == size)) { nbg_printf("failed to query network, parameter is NULL, nbg=%p, property=%d, " "value=%p, size=%d\n", nbg, property, value, size); return NBG_ERROR_FAILURE; } switch (property) { case NBG_PARSER_NETWORK_INPUT_COUNT: if (size >= sizeof(vip_uint32_t)) { *((vip_uint32_t *)value) = nbg_data->fixed.header.input_count; } else { nbg_printf("failed to query network input count, value is a uint32 buffer " "and size is 4byte\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_NETWORK_OUTPUT_COUNT: if (size >= sizeof(vip_uint32_t)) { *((vip_uint32_t *)value) = nbg_data->fixed.header.output_count; } else { nbg_printf("failed to query network output count, value is a uint32 buffer " "and size is 4byte\n"); goOnError(NBG_ERROR_FAILURE); } break; case NBG_PARSER_NETWORK_NAME: { nbg_uint32_t len = nbg_strlen(nbg_data->fixed.header.network_name) + 1; if (size >= len) { nbg_strcpy((nbg_char_t *)value, nbg_data->fixed.header.network_name); } else { nbg_printf("failed to query network name, the size of value buffer should be more than %dbyte\n", len); goOnError(NBG_ERROR_FAILURE); } } break; case NBG_PARSER_NETWORK_NAME_SIZE: { nbg_uint32_t len = nbg_strlen(nbg_data->fixed.header.network_name) + 1; if (size >= sizeof(vip_uint32_t)) { *((vip_uint32_t *)value) = len; } else { nbg_printf("failed to query network name size, value is a uint32 buffer " "and size is 4byte\n"); goOnError(NBG_ERROR_FAILURE); } } break; case NBG_PARSER_NETWORK_CID: { *((vip_uint32_t *)value) = nbg_data->fixed.header.hw_target; } break; default: nbg_printf("not support this property=%d\n", property); status = NBG_ERROR_INVALID_ARGUMENTS; break; } onError: return status; } /* @brief, destroy nbg parser. @param, the nbg object created by NBG data. */ nbg_status_e nbg_parser_destroy( nbg_parser_data nbg ) { nbg_status_e status = NBG_SUCCESS; nbg_parser_data_t *nbg_data = (nbg_parser_data_t*)nbg; if (nbg_data != NBG_NULL) { nbg_data->reader.total_size = 0; nbg_data->reader.offset = 0; if (nbg_data->inputs != NBG_NULL) { nbg_free(nbg_data->inputs); nbg_data->inputs = NBG_NULL; } if (nbg_data->outputs != NBG_NULL) { nbg_free(nbg_data->outputs); nbg_data->outputs = NBG_NULL; } if (nbg_data->orig_layers != NBG_NULL) { nbg_free(nbg_data->orig_layers); nbg_data->orig_layers = NBG_NULL; } if (nbg_data->operations != NBG_NULL) { nbg_free(nbg_data->operations); nbg_data->operations = NBG_NULL; } if (nbg_data->LCDT != NBG_NULL) { nbg_free(nbg_data->LCDT); nbg_data->LCDT = NBG_NULL; } if (nbg_data->pd_entries != NBG_NULL) { nbg_free(nbg_data->pd_entries); nbg_data->pd_entries = NBG_NULL; } if (nbg_data->sh_ops != NBG_NULL) { nbg_free(nbg_data->sh_ops); nbg_data->sh_ops = NBG_NULL; } if (nbg_data->hw_init_ops != NBG_NULL) { nbg_free(nbg_data->hw_init_ops); nbg_data->hw_init_ops = NBG_NULL; } if (nbg_data->ICDT != NBG_NULL) { nbg_free(nbg_data->ICDT); nbg_data->ICDT = NBG_NULL; } if (nbg_data->nn_ops != NBG_NULL) { nbg_free(nbg_data->nn_ops); nbg_data->nn_ops = NBG_NULL; } if (nbg_data->tp_ops != NBG_NULL) { nbg_free(nbg_data->tp_ops); nbg_data->tp_ops = NBG_NULL; } if (nbg_data->LCD != NBG_NULL) { nbg_free(nbg_data->LCD); nbg_data->LCD = NBG_NULL; } nbg_free(nbg); } return status; }