33 #include "../internal.h"
36 #include <openvino/c/openvino.h>
38 #include <c_api/ie_c_api.h>
95 #define APPEND_STRING(generated_string, iterate_string) \
96 generated_string = generated_string ? av_asprintf("%s %s", generated_string, iterate_string) : \
97 av_asprintf("%s", iterate_string);
99 #define OFFSET(x) offsetof(OVContext, x)
100 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM
110 {
"scale",
"Add scale preprocess operation. Divide each element of input by specified value.",
OFFSET(
options.scale),
AV_OPT_TYPE_FLOAT, { .dbl = 0 }, INT_MIN, INT_MAX,
FLAGS},
111 {
"mean",
"Add mean preprocess operation. Subtract specified value from each element of input.",
OFFSET(
options.mean),
AV_OPT_TYPE_FLOAT, { .dbl = 0 }, INT_MIN, INT_MAX,
FLAGS},
118 static const struct {
123 { OK, 0,
"success" },
125 { NOT_IMPLEMENTED,
AVERROR(ENOSYS),
"not implemented" },
127 { PARAMETER_MISMATCH,
AVERROR(EINVAL),
"parameter mismatch" },
129 { OUT_OF_BOUNDS,
AVERROR(EOVERFLOW),
"out of bounds" },
131 { REQUEST_BUSY,
AVERROR(EBUSY),
"request busy" },
132 { RESULT_NOT_READY,
AVERROR(EBUSY),
"result not ready" },
133 { NOT_ALLOCATED,
AVERROR(ENODATA),
"not allocated" },
136 { INFER_CANCELLED,
AVERROR(ECANCELED),
"infer cancelled" },
137 { INVALID_C_PARAM,
AVERROR(EINVAL),
"invalid C parameter" },
139 { NOT_IMPLEMENT_C_METHOD,
AVERROR(ENOSYS),
"not implement C method" },
154 *
desc =
"unknown error";
186 return sizeof(
float);
188 return sizeof(uint8_t);
204 ov_tensor_t* tensor =
NULL;
205 ov_shape_t input_shape = {0};
206 ov_element_type_e precision;
207 void *input_data_ptr =
NULL;
210 precision_e precision;
211 ie_blob_buffer_t blob_buffer;
213 ie_blob_t *input_blob =
NULL;
222 if (!ov_model_is_dynamic(ov_model->
ov_model)) {
224 ov_output_const_port_free(ov_model->
input_port);
237 dims = input_shape.dims;
241 ov_shape_free(&input_shape);
250 input.channels = dims[3];
254 ov_shape_free(&input_shape);
257 input_data_ptr =
input.data;
265 status |= ie_blob_get_dims(input_blob, &dims);
266 status |= ie_blob_get_precision(input_blob, &precision);
268 ie_blob_free(&input_blob);
273 status = ie_blob_get_buffer(input_blob, &blob_buffer);
275 ie_blob_free(&input_blob);
281 input.channels = dims.dims[1];
282 input.data = blob_buffer.buffer;
292 for (
int i = 0;
i <
ctx->options.batch_size; ++
i) {
321 status = ov_tensor_create_from_host_ptr(precision, input_shape,
input.data, &tensor);
322 ov_shape_free(&input_shape);
339 ie_blob_free(&input_blob);
357 ov_tensor_t *output_tensor;
358 ov_shape_t output_shape = {0};
359 ov_element_type_e precision;
362 status = ov_infer_request_get_output_tensor_by_index(request->
infer_request, 0, &output_tensor);
365 "Failed to get output tensor.");
372 "Failed to get output data.");
376 status = ov_tensor_get_shape(output_tensor, &output_shape);
381 dims = output_shape.dims;
386 ov_shape_free(&output_shape);
389 output.channels = dims[1];
393 ov_shape_free(&output_shape);
397 ie_blob_t *output_blob =
NULL;
398 ie_blob_buffer_t blob_buffer;
399 precision_e precision;
403 "output \"%s\" may not correct, all output(s) are: \"%s\"\n",
408 status = ie_blob_get_buffer(output_blob, &blob_buffer);
410 ie_blob_free(&output_blob);
415 status |= ie_blob_get_dims(output_blob, &dims);
416 status |= ie_blob_get_precision(output_blob, &precision);
418 ie_blob_free(&output_blob);
422 output.data = blob_buffer.buffer;
423 output.channels = dims.dims[1];
424 output.height = dims.dims[2];
425 output.width = dims.dims[3];
475 ie_blob_free(&output_blob);
494 if (!model || !*model)
497 ov_model = (*model)->
model;
527 ov_output_const_port_free(ov_model->
input_port);
531 ov_preprocess_prepostprocessor_free(ov_model->
preprocess);
537 ov_core_free(ov_model->
core);
542 ie_network_free(&ov_model->
network);
544 ie_core_free(&ov_model->
core);
560 ov_preprocess_input_tensor_info_t* input_tensor_info =
NULL;
561 ov_preprocess_output_tensor_info_t* output_tensor_info =
NULL;
562 ov_preprocess_input_model_info_t* input_model_info =
NULL;
563 ov_model_t *tmp_ov_model;
564 ov_layout_t* NHWC_layout =
NULL;
565 ov_layout_t* NCHW_layout =
NULL;
566 const char* NHWC_desc =
"NHWC";
567 const char* NCHW_desc =
"NCHW";
568 const char* device =
ctx->options.device_type;
571 ie_available_devices_t a_dev;
573 char *all_dev_names =
NULL;
579 if (
ctx->options.batch_size <= 0) {
580 ctx->options.batch_size = 1;
583 if (
ctx->options.batch_size > 1) {
585 "change batch_size to 1.\n");
586 ctx->options.batch_size = 1;
604 status = ov_preprocess_input_info_get_tensor_info(ov_model->
input_info, &input_tensor_info);
605 status |= ov_preprocess_output_info_get_tensor_info(ov_model->
output_info, &output_tensor_info);
613 status = ov_layout_create(NHWC_desc, &NHWC_layout);
614 status |= ov_layout_create(NCHW_desc, &NCHW_layout);
621 status = ov_preprocess_input_tensor_info_set_layout(input_tensor_info, NHWC_layout);
628 status = ov_preprocess_input_info_get_model_info(ov_model->
input_info, &input_model_info);
635 status = ov_preprocess_input_model_info_set_layout(input_model_info, NCHW_layout);
637 status = ov_preprocess_input_model_info_set_layout(input_model_info, NHWC_layout);
644 status = ov_preprocess_input_tensor_info_set_element_type(input_tensor_info, U8);
646 status |= ov_preprocess_output_set_element_type(output_tensor_info, F32);
648 status |= ov_preprocess_output_set_element_type(output_tensor_info, F32);
650 status |= ov_preprocess_output_set_element_type(output_tensor_info, U8);
658 ov_preprocess_preprocess_steps_t* input_process_steps =
NULL;
659 status = ov_preprocess_input_info_get_preprocess_steps(ov_model->
input_info, &input_process_steps);
665 status = ov_preprocess_preprocess_steps_convert_element_type(input_process_steps, F32);
666 status |= ov_preprocess_preprocess_steps_mean(input_process_steps,
ctx->options.mean);
667 status |= ov_preprocess_preprocess_steps_scale(input_process_steps,
ctx->options.scale);
673 ov_preprocess_preprocess_steps_free(input_process_steps);
685 ov_model_free(tmp_ov_model);
703 ov_preprocess_input_model_info_free(input_model_info);
704 ov_layout_free(NCHW_layout);
705 ov_layout_free(NHWC_layout);
707 if (
ctx->options.batch_size > 1) {
708 input_shapes_t input_shapes;
709 status = ie_network_get_input_shapes(ov_model->
network, &input_shapes);
714 for (
int i = 0;
i < input_shapes.shape_num;
i++)
715 input_shapes.shapes[
i].shape.dims[0] =
ctx->options.batch_size;
716 status = ie_network_reshape(ov_model->
network, input_shapes);
717 ie_network_input_shapes_free(&input_shapes);
726 status = ie_network_set_input_layout(ov_model->
network, input_name, NHWC);
728 if (
status == NOT_FOUND) {
737 status = ie_network_set_output_layout(ov_model->
network, output_name, NHWC);
739 if (
status == NOT_FOUND) {
756 status = ie_network_set_input_precision(ov_model->
network, input_name, U8);
767 status = ie_core_get_available_devices(ov_model->
core, &a_dev);
773 for (
int i = 0;
i < a_dev.num_devices;
i++) {
774 APPEND_STRING(all_dev_names, a_dev.devices[
i])
777 ctx->options.device_type, all_dev_names);
783 if (
ctx->options.nireq <= 0) {
794 for (
int i = 0;
i <
ctx->options.nireq;
i++) {
852 ov_layout_free(NCHW_layout);
854 ov_layout_free(NHWC_layout);
855 if (input_model_info)
856 ov_preprocess_input_model_info_free(input_model_info);
887 ov_model = task->
model;
963 int input_resizable =
ctx->options.input_resizable;
966 ov_shape_t input_shape = {0};
967 ov_element_type_e precision;
970 if (!ov_model_is_dynamic(ov_model->
ov_model)) {
982 dims = input_shape.dims;
994 input->channels = dims[1];
996 input->
width = input_resizable ? -1 : dims[3];
1001 char *model_input_name =
NULL;
1003 size_t model_input_count = 0;
1005 precision_e precision;
1006 status = ie_network_get_inputs_number(ov_model->
network, &model_input_count);
1011 for (
size_t i = 0;
i < model_input_count;
i++) {
1012 status = ie_network_get_input_name(ov_model->
network,
i, &model_input_name);
1017 if (strcmp(model_input_name, input_name) == 0) {
1018 ie_network_name_free(&model_input_name);
1019 status |= ie_network_get_input_dims(ov_model->
network, input_name, &dims);
1020 status |= ie_network_get_input_precision(ov_model->
network, input_name, &precision);
1026 input->channels = dims.dims[1];
1027 input->
height = input_resizable ? -1 : dims.dims[2];
1028 input->
width = input_resizable ? -1 : dims.dims[3];
1033 ie_network_name_free(&model_input_name);
1061 for (uint32_t
i = 0;
i <
header->nb_bboxes;
i++) {
1063 if (bbox->
x < 0 || bbox->
w < 0 || bbox->
x + bbox->
w >=
frame->
width) {
1066 if (bbox->
y < 0 || bbox->
h < 0 || bbox->
y + bbox->
h >=
frame->
width) {
1080 switch (func_type) {
1090 lltask->
task = task;
1129 lltask->
task = task;
1144 static int get_output_ov(
void *model,
const char *input_name,
int input_width,
int input_height,
1145 const char *output_name,
int *output_width,
int *output_height)
1148 ov_dimension_t dims[4] = {{1, 1}, {1, 1}, {input_height, input_height}, {input_width, input_width}};
1150 ov_shape_t input_shape = {0};
1151 ov_partial_shape_t partial_shape;
1154 input_shapes_t input_shapes;
1163 .output_names = &output_name,
1175 if (
ctx->options.input_resizable) {
1176 if (!ov_model_is_dynamic(ov_model->
ov_model)) {
1177 status = ov_partial_shape_create(4, dims, &partial_shape);
1183 input_shape.dims[2] = input_height;
1184 input_shape.dims[3] = input_width;
1190 status = ov_shape_to_partial_shape(input_shape, &partial_shape);
1196 status = ov_model_reshape_single_input(ov_model->
ov_model, partial_shape);
1214 if (
ctx->options.input_resizable) {
1215 status = ie_network_get_input_shapes(ov_model->
network, &input_shapes);
1216 input_shapes.shapes->shape.dims[2] = input_height;
1217 input_shapes.shapes->shape.dims[3] = input_width;
1218 status |= ie_network_reshape(ov_model->
network, input_shapes);
1219 ie_network_input_shapes_free(&input_shapes);
1267 ov_core_t* core =
NULL;
1268 ov_model_t* ovmodel =
NULL;
1271 size_t node_count = 0;
1272 char *node_name =
NULL;
1286 model->
model = ov_model;
1287 ov_model->
model = model;
1288 ov_model->
ctx.
class = &dnn_openvino_class;
1299 status = ov_core_create(&core);
1303 ov_model->
core = core;
1305 status = ov_core_read_model(core, model_filename,
NULL, &ovmodel);
1308 status = ov_get_openvino_version(&ver);
1310 "Please check if the model version matches the runtime OpenVINO Version:\n",
1315 ov_version_free(&ver);
1323 status = ie_core_create(
"", &ov_model->
core);
1330 ver = ie_c_api_version();
1332 "Please check if the model version matches the runtime OpenVINO %s\n",
1333 model_filename, ver.api_version);
1334 ie_version_free(&ver);
1339 status = ie_network_get_inputs_number(ov_model->
network, &node_count);
1344 for (
size_t i = 0;
i < node_count;
i++) {
1345 status = ie_network_get_input_name(ov_model->
network,
i, &node_name);
1351 ie_network_name_free(&node_name);
1353 status = ie_network_get_outputs_number(ov_model->
network, &node_count);
1358 for (
size_t i = 0;
i < node_count;
i++) {
1359 status = ie_network_get_output_name(ov_model->
network,
i, &node_name);
1365 ie_network_name_free(&node_name);
1431 if (
ctx->options.async) {
1455 if (
ctx->options.batch_size > 1) {
1475 static int dnn_flush_ov(
const DNNModel *model)
1527 .execute_model = dnn_execute_model_ov,
1528 .get_result = dnn_get_result_ov,
1529 .flush = dnn_flush_ov,