History

lavfi/dnn: Add OpenVINO API 2.0 support

OpenVINO API 2.0 was released in March 2022, which introduced new features. This commit implements current OpenVINO features with new 2.0 APIs. And will add other features in API 2.0. Please add installation path, which include openvino.pc, to PKG_CONFIG_PATH mannually for new OpenVINO libs config.

Wenbin Chen committed 3 years ago

Commit e79bd1f1 parent 80ad0e22 files · +487 −34Browse files

Showing the changes to libavfilter (1 of 2 files). Show all

Unified · Split

libavfilter/dnn/dnn_backend_openvino.c+483−32
@@ -32,7 +32,11 @@ · 31 unmodified lines
3232 #include "libavutil/detection_bbox.h"
3333 #include "../internal.h"
3434 #include "safe_queue.h"
35+#if HAVE_OPENVINO2
36+#include <openvino/c/openvino.h>
37+#else
3538 #include <c_api/ie_c_api.h>
39+#endif
3640 #include "dnn_backend_common.h"
3741
3842 typedef struct OVOptions{
@@ -51,9 +55,20 @@ typedef struct OVContext { · 12 unmodified lines
5155 typedef struct OVModel{
5256 OVContext ctx;
5357 DNNModel *model;
58+#if HAVE_OPENVINO2
59+ ov_core_t *core;
60+ ov_model_t *ov_model;
61+ ov_compiled_model_t *compiled_model;
62+ ov_output_const_port_t* input_port;
63+ ov_preprocess_input_info_t* input_info;
64+ ov_output_const_port_t* output_port;
65+ ov_preprocess_output_info_t* output_info;
66+ ov_preprocess_prepostprocessor_t* preprocess;
67+#else
5468 ie_core_t *core;
5569 ie_network_t *network;
5670 ie_executable_network_t *exe_network;
71+#endif
5772 SafeQueue *request_queue; // holds OVRequestItem
5873 Queue *task_queue; // holds TaskItem
5974 Queue *lltask_queue; // holds LastLevelTaskItem
@@ -63,10 +78,15 @@ typedef struct OVModel{ · 3 unmodified lines
6378
6479 // one request for one call to openvino
6580 typedef struct OVRequestItem {
66− ie_infer_request_t *infer_request;
6781 LastLevelTaskItem **lltasks;
6882 uint32_t lltask_count;
83+#if HAVE_OPENVINO2
84+ ov_infer_request_t *infer_request;
85+ ov_callback_t callback;
86+#else
6987 ie_complete_call_back_t callback;
88+ ie_infer_request_t *infer_request;
89+#endif
7090 } OVRequestItem;
7191
7292 #define APPEND_STRING(generated_string, iterate_string) \
@@ -85,11 +105,61 @@ static const AVOption dnn_openvino_options[] = { · 12 unmodified lines
85105
86106 AVFILTER_DEFINE_CLASS(dnn_openvino);
87107
108+#if HAVE_OPENVINO2
109+static const struct {
110+ ov_status_e status;
111+ int av_err;
112+ const char *desc;
113+} ov2_errors[] = {
114+ { OK, 0, "success" },
115+ { GENERAL_ERROR, AVERROR_EXTERNAL, "general error" },
116+ { NOT_IMPLEMENTED, AVERROR(ENOSYS), "not implemented" },
117+ { NETWORK_NOT_LOADED, AVERROR_EXTERNAL, "network not loaded" },
118+ { PARAMETER_MISMATCH, AVERROR(EINVAL), "parameter mismatch" },
119+ { NOT_FOUND, AVERROR_EXTERNAL, "not found" },
120+ { OUT_OF_BOUNDS, AVERROR(EOVERFLOW), "out of bounds" },
121+ { UNEXPECTED, AVERROR_EXTERNAL, "unexpected" },
122+ { REQUEST_BUSY, AVERROR(EBUSY), "request busy" },
123+ { RESULT_NOT_READY, AVERROR(EBUSY), "result not ready" },
124+ { NOT_ALLOCATED, AVERROR(ENODATA), "not allocated" },
125+ { INFER_NOT_STARTED, AVERROR_EXTERNAL, "infer not started" },
126+ { NETWORK_NOT_READ, AVERROR_EXTERNAL, "network not read" },
127+ { INFER_CANCELLED, AVERROR(ECANCELED), "infer cancelled" },
128+ { INVALID_C_PARAM, AVERROR(EINVAL), "invalid C parameter" },
129+ { UNKNOWN_C_ERROR, AVERROR_UNKNOWN, "unknown C error" },
130+ { NOT_IMPLEMENT_C_METHOD, AVERROR(ENOSYS), "not implement C method" },
131+ { UNKNOW_EXCEPTION, AVERROR_UNKNOWN, "unknown exception" },
132+};
133+
134+static int ov2_map_error(ov_status_e status, const char **desc)
135+{
136+ int i;
137+ for (i = 0; i < FF_ARRAY_ELEMS(ov2_errors); i++) {
138+ if (ov2_errors[i].status == status) {
139+ if (desc)
140+ *desc = ov2_errors[i].desc;
141+ return ov2_errors[i].av_err;
142+ }
143+ }
144+ if (desc)
145+ *desc = "unknown error";
146+ return AVERROR_UNKNOWN;
147+}
148+#endif
149+
150+#if HAVE_OPENVINO2
151+static DNNDataType precision_to_datatype(ov_element_type_e precision)
152+#else
88153 static DNNDataType precision_to_datatype(precision_e precision)
154+#endif
89155 {
90156 switch (precision)
91157 {
158+#if HAVE_OPENVINO2
159+ case F32:
160+#else
92161 case FP32:
162+#endif
93163 return DNN_FLOAT;
94164 case U8:
95165 return DNN_UINT8;
@@ -115,20 +185,61 @@ static int get_datatype_size(DNNDataType dt) · 19 unmodified lines
115185
116186 static int fill_model_input_ov(OVModel *ov_model, OVRequestItem *request)
117187 {
188+ DNNData input;
189+ LastLevelTaskItem *lltask;
190+ TaskItem *task;
191+ OVContext *ctx = &ov_model->ctx;
192+#if HAVE_OPENVINO2
193+ int64_t* dims;
194+ ov_status_e status;
195+ ov_tensor_t* tensor = NULL;
196+ ov_shape_t input_shape = {0};
197+ ov_element_type_e precision;
198+ void *input_data_ptr = NULL;
199+#else
118200 dimensions_t dims;
119201 precision_e precision;
120202 ie_blob_buffer_t blob_buffer;
121− OVContext *ctx = &ov_model->ctx;
122203 IEStatusCode status;
123− DNNData input;
124204 ie_blob_t *input_blob = NULL;
125− LastLevelTaskItem *lltask;
126− TaskItem *task;
205+#endif
127206
128207 lltask = ff_queue_peek_front(ov_model->lltask_queue);
129208 av_assert0(lltask);
130209 task = lltask->task;
131210
211+#if HAVE_OPENVINO2
212+ if (!ov_model_is_dynamic(ov_model->ov_model)) {
213+ ov_output_const_port_free(ov_model->input_port);
214+ status = ov_model_const_input_by_name(ov_model->ov_model, task->input_name, &ov_model->input_port);
215+ if (status != OK) {
216+ av_log(ctx, AV_LOG_ERROR, "Failed to get input port shape.\n");
217+ return ov2_map_error(status, NULL);
218+ }
219+ status = ov_const_port_get_shape(ov_model->input_port, &input_shape);
220+ if (status != OK) {
221+ av_log(ctx, AV_LOG_ERROR, "Failed to get input port shape.\n");
222+ return ov2_map_error(status, NULL);
223+ }
224+ dims = input_shape.dims;
225+ status = ov_port_get_element_type(ov_model->input_port, &precision);
226+ if (status != OK) {
227+ av_log(ctx, AV_LOG_ERROR, "Failed to get input port data type.\n");
228+ return ov2_map_error(status, NULL);
229+ }
230+ } else {
231+ avpriv_report_missing_feature(ctx, "Do not support dynamic model.");
232+ return AVERROR(ENOSYS);
233+ }
234+ input.height = dims[2];
235+ input.width = dims[3];
236+ input.channels = dims[1];
237+ input.dt = precision_to_datatype(precision);
238+ input.data = av_malloc(input.height * input.width * input.channels * get_datatype_size(input.dt));
239+ if (!input.data)
240+ return AVERROR(ENOMEM);
241+ input_data_ptr = input.data;
242+#else
132243 status = ie_infer_request_get_blob(request->infer_request, task->input_name, &input_blob);
133244 if (status != OK) {
134245 av_log(ctx, AV_LOG_ERROR, "Failed to get input blob with name %s\n", task->input_name);
@@ -149,12 +260,12 @@ static int fill_model_input_ov(OVModel *ov_model, OVRequestItem *request) · 14 unmodified lines
149260 av_log(ctx, AV_LOG_ERROR, "Failed to get input blob buffer\n");
150261 return DNN_GENERIC_ERROR;
151262 }
152−
153263 input.height = dims.dims[2];
154264 input.width = dims.dims[3];
155265 input.channels = dims.dims[1];
156266 input.data = blob_buffer.buffer;
157267 input.dt = precision_to_datatype(precision);
268+#endif
158269 // all models in openvino open model zoo use BGR as input,
159270 // change to be an option when necessary.
160271 input.order = DCO_BGR;
@@ -187,29 +298,82 @@ static int fill_model_input_ov(OVModel *ov_model, OVRequestItem *request) · 26 unmodified lines
187298 av_assert0(!"should not reach here");
188299 break;
189300 }
301+#if HAVE_OPENVINO2
302+ status = ov_tensor_create_from_host_ptr(precision, input_shape, input.data, &tensor);
303+ if (status != OK) {
304+ av_log(ctx, AV_LOG_ERROR, "Failed to create tensor from host prt.\n");
305+ return ov2_map_error(status, NULL);
306+ }
307+ status = ov_infer_request_set_input_tensor(request->infer_request, tensor);
308+ if (status != OK) {
309+ av_log(ctx, AV_LOG_ERROR, "Failed to Set an input tensor for the model.\n");
310+ return ov2_map_error(status, NULL);
311+ }
312+#endif
190313 input.data = (uint8_t *)input.data
191314 + input.width * input.height * input.channels * get_datatype_size(input.dt);
192315 }
316+#if HAVE_OPENVINO2
317+ av_freep(&input_data_ptr);
318+#else
193319 ie_blob_free(&input_blob);
320+#endif
194321
195322 return 0;
196323 }
197324
198325 static void infer_completion_callback(void *args)
199326 {
200− dimensions_t dims;
201− precision_e precision;
202− IEStatusCode status;
203327 OVRequestItem *request = args;
204328 LastLevelTaskItem *lltask = request->lltasks[0];
205329 TaskItem *task = lltask->task;
206330 OVModel *ov_model = task->model;
207331 SafeQueue *requestq = ov_model->request_queue;
208− ie_blob_t *output_blob = NULL;
209− ie_blob_buffer_t blob_buffer;
210332 DNNData output;
211333 OVContext *ctx = &ov_model->ctx;
334+#if HAVE_OPENVINO2
335+ size_t* dims;
336+ ov_status_e status;
337+ ov_tensor_t *output_tensor;
338+ ov_shape_t output_shape = {0};
339+ ov_element_type_e precision;
340+
341+ status = ov_infer_request_get_output_tensor_by_index(request->infer_request, 0, &output_tensor);
342+ if (status != OK) {
343+ av_log(ctx, AV_LOG_ERROR,
344+ "Failed to get output tensor.");
345+ return;
346+ }
347+
348+ status = ov_tensor_data(output_tensor, &output.data);
349+ if (status != OK) {
350+ av_log(ctx, AV_LOG_ERROR,
351+ "Failed to get output data.");
352+ return;
353+ }
212354
355+ status = ov_tensor_get_shape(output_tensor, &output_shape);
356+ if (status != OK) {
357+ av_log(ctx, AV_LOG_ERROR, "Failed to get output port shape.\n");
358+ return;
359+ }
360+ dims = output_shape.dims;
361+
362+ status = ov_port_get_element_type(ov_model->output_port, &precision);
363+ if (status != OK) {
364+ av_log(ctx, AV_LOG_ERROR, "Failed to get output port data type.\n");
365+ return;
366+ }
367+ output.channels = dims[1];
368+ output.height = dims[2];
369+ output.width = dims[3];
370+ av_assert0(request->lltask_count <= dims[0]);
371+#else
372+ IEStatusCode status;
373+ dimensions_t dims;
374+ ie_blob_t *output_blob = NULL;
375+ ie_blob_buffer_t blob_buffer;
376+ precision_e precision;
213377 status = ie_infer_request_get_blob(request->infer_request, task->output_names[0], &output_blob);
214378 if (status != OK) {
215379 av_log(ctx, AV_LOG_ERROR,
@@ -232,14 +396,14 @@ static void infer_completion_callback(void *args) · 16 unmodified lines
232396 av_log(ctx, AV_LOG_ERROR, "Failed to get dims or precision of output\n");
233397 return;
234398 }
235−
399+ output.data = blob_buffer.buffer;
236400 output.channels = dims.dims[1];
237401 output.height = dims.dims[2];
238402 output.width = dims.dims[3];
403+ av_assert0(request->lltask_count <= dims.dims[0]);
404+#endif
239405 output.dt = precision_to_datatype(precision);
240− output.data = blob_buffer.buffer;
241406
242− av_assert0(request->lltask_count <= dims.dims[0]);
243407 av_assert0(request->lltask_count >= 1);
244408 for (int i = 0; i < request->lltask_count; ++i) {
245409 task = request->lltasks[i]->task;
@@ -281,11 +445,16 @@ static void infer_completion_callback(void *args) · 35 unmodified lines
281445 output.data = (uint8_t *)output.data
282446 + output.width * output.height * output.channels * get_datatype_size(output.dt);
283447 }
448+#if !HAVE_OPENVINO2
284449 ie_blob_free(&output_blob);
285−
450+#endif
286451 request->lltask_count = 0;
287452 if (ff_safe_queue_push_back(requestq, request) < 0) {
453+#if HAVE_OPENVINO2
454+ ov_infer_request_free(request->infer_request);
455+#else
288456 ie_infer_request_free(&request->infer_request);
457+#endif
289458 av_freep(&request);
290459 av_log(ctx, AV_LOG_ERROR, "Failed to push back request_queue.\n");
291460 return;
@@ -299,7 +468,11 @@ static void dnn_free_model_ov(DNNModel **model) · 7 unmodified lines
299468 while (ff_safe_queue_size(ov_model->request_queue) != 0) {
300469 OVRequestItem *item = ff_safe_queue_pop_front(ov_model->request_queue);
301470 if (item && item->infer_request) {
471+#if HAVE_OPENVINO2
472+ ov_infer_request_free(item->infer_request);
473+#else
302474 ie_infer_request_free(&item->infer_request);
475+#endif
303476 }
304477 av_freep(&item->lltasks);
305478 av_freep(&item);
@@ -319,13 +492,23 @@ static void dnn_free_model_ov(DNNModel **model) · 13 unmodified lines
319492 av_freep(&item);
320493 }
321494 ff_queue_destroy(ov_model->task_queue);
322−
495+#if HAVE_OPENVINO2
496+ if (ov_model->preprocess)
497+ ov_preprocess_prepostprocessor_free(ov_model->preprocess);
498+ if (ov_model->compiled_model)
499+ ov_compiled_model_free(ov_model->compiled_model);
500+ if (ov_model->ov_model)
501+ ov_model_free(ov_model->ov_model);
502+ if (ov_model->core)
503+ ov_core_free(ov_model->core);
504+#else
323505 if (ov_model->exe_network)
324506 ie_exec_network_free(&ov_model->exe_network);
325507 if (ov_model->network)
326508 ie_network_free(&ov_model->network);
327509 if (ov_model->core)
328510 ie_core_free(&ov_model->core);
511+#endif
329512 av_freep(&ov_model);
330513 av_freep(model);
331514 }
@@ -336,16 +519,106 @@ static int init_model_ov(OVModel *ov_model, const char *input_name, const char * · 4 unmodified lines
336519 {
337520 int ret = 0;
338521 OVContext *ctx = &ov_model->ctx;
522+#if HAVE_OPENVINO2
523+ ov_status_e status;
524+ ov_preprocess_input_tensor_info_t* input_tensor_info;
525+ ov_preprocess_output_tensor_info_t* output_tensor_info;
526+ ov_model_t *tmp_ov_model;
527+ ov_layout_t* NHWC_layout = NULL;
528+ const char* NHWC_desc = "NHWC";
529+ const char* device = ctx->options.device_type;
530+#else
339531 IEStatusCode status;
340532 ie_available_devices_t a_dev;
341533 ie_config_t config = {NULL, NULL, NULL};
342534 char *all_dev_names = NULL;
535+#endif
343536
344537 // batch size
345538 if (ctx->options.batch_size <= 0) {
346539 ctx->options.batch_size = 1;
347540 }
541+#if HAVE_OPENVINO2
542+ if (ctx->options.batch_size > 1) {
543+ avpriv_report_missing_feature(ctx, "Do not support batch_size > 1 for now,"
544+ "change batch_size to 1.\n");
545+ ctx->options.batch_size = 1;
546+ }
547+
548+ status = ov_preprocess_prepostprocessor_create(ov_model->ov_model, &ov_model->preprocess);
549+ if (status != OK) {
550+ av_log(ctx, AV_LOG_ERROR, "Failed to create preprocess for ov_model.\n");
551+ ret = ov2_map_error(status, NULL);
552+ goto err;
553+ }
554+
555+ status = ov_preprocess_prepostprocessor_get_input_info_by_name(ov_model->preprocess, input_name, &ov_model->input_info);
556+ status |= ov_preprocess_prepostprocessor_get_output_info_by_name(ov_model->preprocess, output_name, &ov_model->output_info);
557+ if (status != OK) {
558+ av_log(ctx, AV_LOG_ERROR, "Failed to get input/output info from preprocess.\n");
559+ ret = ov2_map_error(status, NULL);
560+ goto err;
561+ }
562+
563+ status = ov_preprocess_input_info_get_tensor_info(ov_model->input_info, &input_tensor_info);
564+ status |= ov_preprocess_output_info_get_tensor_info(ov_model->output_info, &output_tensor_info);
565+ if (status != OK) {
566+ av_log(ctx, AV_LOG_ERROR, "Failed to get tensor info from input/output.\n");
567+ ret = ov2_map_error(status, NULL);
568+ goto err;
569+ }
570+
571+ //set input layout
572+ status = ov_layout_create(NHWC_desc, &NHWC_layout);
573+ if (status != OK) {
574+ av_log(ctx, AV_LOG_ERROR, "Failed to create layout for input.\n");
575+ ret = ov2_map_error(status, NULL);
576+ goto err;
577+ }
578+
579+ status = ov_preprocess_input_tensor_info_set_layout(input_tensor_info, NHWC_layout);
580+ if (status != OK) {
581+ av_log(ctx, AV_LOG_ERROR, "Failed to set input tensor layout\n");
582+ ret = ov2_map_error(status, NULL);
583+ goto err;
584+ }
585+
586+ if (ov_model->model->func_type != DFT_PROCESS_FRAME)
587+ //set precision only for detect and classify
588+ status = ov_preprocess_input_tensor_info_set_element_type(input_tensor_info, U8);
589+ status |= ov_preprocess_output_set_element_type(output_tensor_info, F32);
590+ if (status != OK) {
591+ av_log(ctx, AV_LOG_ERROR, "Failed to set input/output element type\n");
592+ ret = ov2_map_error(status, NULL);
593+ goto err;
594+ }
595+
596+ //update model
597+ if(ov_model->ov_model)
598+ tmp_ov_model = ov_model->ov_model;
599+ status = ov_preprocess_prepostprocessor_build(ov_model->preprocess, &ov_model->ov_model);
600+ if (status != OK) {
601+ av_log(ctx, AV_LOG_ERROR, "Failed to update OV model\n");
602+ ret = ov2_map_error(status, NULL);
603+ goto err;
604+ }
605+ ov_model_free(tmp_ov_model);
348606
607+ //update output_port
608+ if (ov_model->output_port)
609+ ov_output_const_port_free(ov_model->output_port);
610+ status = ov_model_const_output_by_name(ov_model->ov_model, output_name, &ov_model->output_port);
611+ if (status != OK) {
612+ av_log(ctx, AV_LOG_ERROR, "Failed to get output port.\n");
613+ goto err;
614+ }
615+ //compile network
616+ status = ov_core_compile_model(ov_model->core, ov_model->ov_model, device, 0, &ov_model->compiled_model);
617+ if (status != OK) {
618+ ret = ov2_map_error(status, NULL);
619+ goto err;
620+ }
621+#else
349622 if (ctx->options.batch_size > 1) {
350623 input_shapes_t input_shapes;
351624 status = ie_network_get_input_shapes(ov_model->network, &input_shapes);
@@ -420,7 +693,7 @@ static int init_model_ov(OVModel *ov_model, const char *input_name, const char * · 68 unmodified lines
420693 ret = AVERROR(ENODEV);
421694 goto err;
422695 }
423−
696+#endif
424697 // create infer_requests for async execution
425698 if (ctx->options.nireq <= 0) {
426699 // the default value is a rough estimation
@@ -440,7 +713,11 @@ static int init_model_ov(OVModel *ov_model, const char *input_name, const char * · 13 unmodified lines
440713 goto err;
441714 }
442715
716+#if HAVE_OPENVINO2
717+ item->callback.callback_func = infer_completion_callback;
718+#else
443719 item->callback.completeCallBackFunc = infer_completion_callback;
720+#endif
444721 item->callback.args = item;
445722 if (ff_safe_queue_push_back(ov_model->request_queue, item) < 0) {
446723 av_freep(&item);
@@ -448,11 +725,19 @@ static int init_model_ov(OVModel *ov_model, const char *input_name, const char * · 1 unmodified line
448725 goto err;
449726 }
450727
728+#if HAVE_OPENVINO2
729+ status = ov_compiled_model_create_infer_request(ov_model->compiled_model, &item->infer_request);
730+ if (status != OK) {
731+ av_log(ctx, AV_LOG_ERROR, "Failed to Creates an inference request object.\n");
732+ goto err;
733+ }
734+#else
451735 status = ie_exec_network_create_infer_request(ov_model->exe_network, &item->infer_request);
452736 if (status != OK) {
453737 ret = DNN_GENERIC_ERROR;
454738 goto err;
455739 }
740+#endif
456741
457742 item->lltasks = av_malloc_array(ctx->options.batch_size, sizeof(*item->lltasks));
458743 if (!item->lltasks) {
@@ -483,7 +768,11 @@ err: · 24 unmodified lines
483768
484769 static int execute_model_ov(OVRequestItem *request, Queue *inferenceq)
485770 {
771+#if HAVE_OPENVINO2
772+ ov_status_e status;
773+#else
486774 IEStatusCode status;
775+#endif
487776 LastLevelTaskItem *lltask;
488777 int ret = 0;
489778 TaskItem *task;
@@ -491,7 +780,11 @@ static int execute_model_ov(OVRequestItem *request, Queue *inferenceq) · 1 unmodified line
491780 OVModel *ov_model;
492781
493782 if (ff_queue_size(inferenceq) == 0) {
783+#if HAVE_OPENVINO2
784+ ov_infer_request_free(request->infer_request);
785+#else
494786 ie_infer_request_free(&request->infer_request);
787+#endif
495788 av_freep(&request);
496789 return 0;
497790 }
@@ -501,11 +794,39 @@ static int execute_model_ov(OVRequestItem *request, Queue *inferenceq) · 3 unmodified lines
501794 ov_model = task->model;
502795 ctx = &ov_model->ctx;
503796
797+ ret = fill_model_input_ov(ov_model, request);
798+ if (ret != 0) {
799+ goto err;
800+ }
801+
802+#if HAVE_OPENVINO2
504803 if (task->async) {
505− ret = fill_model_input_ov(ov_model, request);
506− if (ret != 0) {
804+ status = ov_infer_request_set_callback(request->infer_request, &request->callback);
805+ if (status != OK) {
806+ av_log(ctx, AV_LOG_ERROR, "Failed to set completion callback for inference\n");
807+ ret = ov2_map_error(status, NULL);
808+ goto err;
809+ }
810+
811+ status = ov_infer_request_start_async(request->infer_request);
812+ if (status != OK) {
813+ av_log(ctx, AV_LOG_ERROR, "Failed to start async inference\n");
814+ ret = ov2_map_error(status, NULL);
815+ goto err;
816+ }
817+ return 0;
818+ } else {
819+ status = ov_infer_request_infer(request->infer_request);
820+ if (status != OK) {
821+ av_log(NULL, AV_LOG_ERROR, "Failed to start synchronous model inference for OV2\n");
822+ ret = ov2_map_error(status, NULL);
507823 goto err;
508824 }
825+ infer_completion_callback(request);
826+ return (task->inference_done == task->inference_todo) ? 0 : DNN_GENERIC_ERROR;
827+ }
828+#else
829+ if (task->async) {
509830 status = ie_infer_set_completion_callback(request->infer_request, &request->callback);
510831 if (status != OK) {
511832 av_log(ctx, AV_LOG_ERROR, "Failed to set completion callback for inference\n");
@@ -520,10 +841,6 @@ static int execute_model_ov(OVRequestItem *request, Queue *inferenceq) · 8 unmodified lines
520841 }
521842 return 0;
522843 } else {
523− ret = fill_model_input_ov(ov_model, request);
524− if (ret != 0) {
525− goto err;
526− }
527844 status = ie_infer_request_infer(request->infer_request);
528845 if (status != OK) {
529846 av_log(ctx, AV_LOG_ERROR, "Failed to start synchronous model inference\n");
@@ -533,9 +850,14 @@ static int execute_model_ov(OVRequestItem *request, Queue *inferenceq) · 3 unmodified lines
533850 infer_completion_callback(request);
534851 return (task->inference_done == task->inference_todo) ? 0 : DNN_GENERIC_ERROR;
535852 }
853+#endif
536854 err:
537855 if (ff_safe_queue_push_back(ov_model->request_queue, request) < 0) {
856+#if HAVE_OPENVINO2
857+ ov_infer_request_free(request->infer_request);
858+#else
538859 ie_infer_request_free(&request->infer_request);
860+#endif
539861 av_freep(&request);
540862 }
541863 return ret;
@@ -545,19 +867,54 @@ static int get_input_ov(void *model, DNNData *input, const char *input_name) · 3 unmodified lines
545867 {
546868 OVModel *ov_model = model;
547869 OVContext *ctx = &ov_model->ctx;
870+ int input_resizable = ctx->options.input_resizable;
871+
872+#if HAVE_OPENVINO2
873+ ov_shape_t input_shape = {0};
874+ ov_element_type_e precision;
875+ int64_t* dims;
876+ ov_status_e status;
877+ if (!ov_model_is_dynamic(ov_model->ov_model)) {
878+ status = ov_model_const_input_by_name(ov_model->ov_model, input_name, &ov_model->input_port);
879+ if (status != OK) {
880+ av_log(ctx, AV_LOG_ERROR, "Failed to get input port shape.\n");
881+ return ov2_map_error(status, NULL);
882+ }
883+
884+ status = ov_const_port_get_shape(ov_model->input_port, &input_shape);
885+ if (status != OK) {
886+ av_log(ctx, AV_LOG_ERROR, "Failed to get input port shape.\n");
887+ return ov2_map_error(status, NULL);
888+ }
889+ dims = input_shape.dims;
890+
891+ status = ov_port_get_element_type(ov_model->input_port, &precision);
892+ if (status != OK) {
893+ av_log(ctx, AV_LOG_ERROR, "Failed to get input port data type.\n");
894+ return ov2_map_error(status, NULL);
895+ }
896+ } else {
897+ avpriv_report_missing_feature(ctx, "Do not support dynamic model now.");
898+ return AVERROR(ENOSYS);
899+ }
900+
901+ input->channels = dims[1];
902+ input->height = input_resizable ? -1 : dims[2];
903+ input->width = input_resizable ? -1 : dims[3];
904+ input->dt = precision_to_datatype(precision);
905+
906+ return 0;
907+#else
548908 char *model_input_name = NULL;
549909 IEStatusCode status;
550910 size_t model_input_count = 0;
551911 dimensions_t dims;
552912 precision_e precision;
553− int input_resizable = ctx->options.input_resizable;
554−
555913 status = ie_network_get_inputs_number(ov_model->network, &model_input_count);
556914 if (status != OK) {
557915 av_log(ctx, AV_LOG_ERROR, "Failed to get input count\n");
558916 return DNN_GENERIC_ERROR;
559917 }
560−
561918 for (size_t i = 0; i < model_input_count; i++) {
562919 status = ie_network_get_input_name(ov_model->network, i, &model_input_name);
563920 if (status != OK) {
@@ -585,6 +942,7 @@ static int get_input_ov(void *model, DNNData *input, const char *input_name) · 21 unmodified lines
585942
586943 av_log(ctx, AV_LOG_ERROR, "Could not find \"%s\" in model, all input(s) are: \"%s\"\n", input_name, ov_model->all_input_names);
587944 return AVERROR(EINVAL);
945+#endif
588946 }
589947
590948 static int contain_valid_detection_bbox(AVFrame *frame)
@@ -693,13 +1051,20 @@ static int extract_lltask_from_task(DNNFunctionType func_type, TaskItem *task, Q · 102 unmodified lines
6931051 static int get_output_ov(void *model, const char *input_name, int input_width, int input_height,
6941052 const char *output_name, int *output_width, int *output_height)
6951053 {
1054+#if HAVE_OPENVINO2
1055+ ov_dimension_t dims[4] = {{1, 1}, {1, 1}, {input_height, input_height}, {input_width, input_width}};
1056+ ov_status_e status;
1057+ ov_shape_t input_shape = {0};
1058+ ov_partial_shape_t partial_shape;
1059+#else
1060+ IEStatusCode status;
1061+ input_shapes_t input_shapes;
1062+#endif
6961063 int ret;
6971064 OVModel *ov_model = model;
6981065 OVContext *ctx = &ov_model->ctx;
6991066 TaskItem task;
7001067 OVRequestItem *request;
701− IEStatusCode status;
702− input_shapes_t input_shapes;
7031068 DNNExecBaseParams exec_params = {
7041069 .input_name = input_name,
7051070 .output_names = &output_name,
@@ -713,6 +1078,46 @@ static int get_output_ov(void *model, const char *input_name, int input_width, i · 7 unmodified lines
7131078 return AVERROR(EINVAL);
7141079 }
7151080
1081+#if HAVE_OPENVINO2
1082+ if (ctx->options.input_resizable) {
1083+ if (!ov_model_is_dynamic(ov_model->ov_model)) {
1084+ status = ov_partial_shape_create(4, dims, &partial_shape);
1085+ if (status != OK) {
1086+ av_log(ctx, AV_LOG_ERROR, "Failed create partial shape.\n");
1087+ goto err;
1088+ }
1089+ status = ov_const_port_get_shape(ov_model->input_port, &input_shape);
1090+ input_shape.dims[2] = input_height;
1091+ input_shape.dims[3] = input_width;
1092+ if (status != OK) {
1093+ av_log(ctx, AV_LOG_ERROR, "Failed create shape for model input resize.\n");
1094+ goto err;
1095+ }
1096+
1097+ status = ov_shape_to_partial_shape(input_shape, &partial_shape);
1098+ if (status != OK) {
1099+ av_log(ctx, AV_LOG_ERROR, "Failed create partial shape for model input resize.\n");
1100+ goto err;
1101+ }
1102+
1103+ status = ov_model_reshape_single_input(ov_model->ov_model, partial_shape);
1104+ if (status != OK) {
1105+ av_log(ctx, AV_LOG_ERROR, "Failed to reszie model input.\n");
1106+ goto err;
1107+ }
1108+ } else {
1109+ avpriv_report_missing_feature(ctx, "Do not support dynamic model.");
1110+ goto err;
1111+ }
1112+ }
1113+
1114+ status = ov_model_const_output_by_name(ov_model->ov_model, output_name, &ov_model->output_port);
1115+ if (status != OK) {
1116+ av_log(ctx, AV_LOG_ERROR, "Failed to get output port.\n");
1117+ goto err;
1118+ }
1119+ if (!ov_model->compiled_model) {
1120+#else
7161121 if (ctx->options.input_resizable) {
7171122 status = ie_network_get_input_shapes(ov_model->network, &input_shapes);
7181123 input_shapes.shapes->shape.dims[2] = input_height;
@@ -724,8 +1129,8 @@ static int get_output_ov(void *model, const char *input_name, int input_width, i · 5 unmodified lines
7241129 return DNN_GENERIC_ERROR;
7251130 }
7261131 }
727−
7281132 if (!ov_model->exe_network) {
1133+#endif
7291134 ret = init_model_ov(ov_model, input_name, output_name);
7301135 if (ret != 0) {
7311136 av_log(ctx, AV_LOG_ERROR, "Failed init OpenVINO exectuable network or inference request\n");
@@ -765,9 +1170,15 @@ static DNNModel *dnn_load_model_ov(const char *model_filename, DNNFunctionType f · 33 unmodified lines
7651170 DNNModel *model = NULL;
7661171 OVModel *ov_model = NULL;
7671172 OVContext *ctx = NULL;
768− IEStatusCode status;
1173+#if HAVE_OPENVINO2
1174+ ov_core_t* core = NULL;
1175+ ov_model_t* ovmodel = NULL;
1176+ ov_status_e status;
1177+#else
7691178 size_t node_count = 0;
7701179 char *node_name = NULL;
1180+ IEStatusCode status;
1181+#endif
7711182
7721183 model = av_mallocz(sizeof(DNNModel));
7731184 if (!model){
@@ -783,8 +1194,6 @@ static DNNModel *dnn_load_model_ov(const char *model_filename, DNNFunctionType f · 9 unmodified lines
7831194 ov_model->model = model;
7841195 ov_model->ctx.class = &dnn_openvino_class;
7851196 ctx = &ov_model->ctx;
786− ov_model->all_input_names = NULL;
787− ov_model->all_output_names = NULL;
7881197
7891198 //parse options
7901199 av_opt_set_defaults(ctx);
@@ -793,6 +1202,31 @@ static DNNModel *dnn_load_model_ov(const char *model_filename, DNNFunctionType f · 2 unmodified lines
7931202 goto err;
7941203 }
7951204
1205+#if HAVE_OPENVINO2
1206+ status = ov_core_create(&core);
1207+ if (status != OK) {
1208+ goto err;
1209+ }
1210+
1211+ status = ov_core_read_model(core, model_filename, NULL, &ovmodel);
1212+ if (status != OK) {
1213+ ov_version_t ver;
1214+ status = ov_get_openvino_version(&ver);
1215+ av_log(NULL, AV_LOG_ERROR, "Failed to read the network from model file %s,\n"
1216+ "Please check if the model version matches the runtime OpenVINO Version:\n",
1217+ model_filename);
1218+ if (status == OK) {
1219+ av_log(NULL, AV_LOG_ERROR, "BuildNumber: %s\n", ver.buildNumber);
1220+ }
1221+ ov_version_free(&ver);
1222+ goto err;
1223+ }
1224+ ov_model->ov_model = ovmodel;
1225+ ov_model->core = core;
1226+#else
1227+ ov_model->all_input_names = NULL;
1228+ ov_model->all_output_names = NULL;
1229+
7961230 status = ie_core_create("", &ov_model->core);
7971231 if (status != OK)
7981232 goto err;
@@ -835,6 +1269,7 @@ static DNNModel *dnn_load_model_ov(const char *model_filename, DNNFunctionType f · 36 unmodified lines
8351269 }
8361270 APPEND_STRING(ov_model->all_output_names, node_name)
8371271 }
1272+#endif
8381273
8391274 model->get_input = &get_input_ov;
8401275 model->get_output = &get_output_ov;
@@ -862,7 +1297,11 @@ static int dnn_execute_model_ov(const DNNModel *model, DNNExecBaseParams *exec_p · 21 unmodified lines
8621297 return ret;
8631298 }
8641299
1300+#if HAVE_OPENVINO2
1301+ if (!ov_model->compiled_model) {
1302+#else
8651303 if (!ov_model->exe_network) {
1304+#endif
8661305 ret = init_model_ov(ov_model, exec_params->input_name, exec_params->output_names[0]);
8671306 if (ret != 0) {
8681307 av_log(ctx, AV_LOG_ERROR, "Failed init OpenVINO exectuable network or inference request\n");
@@ -943,7 +1382,11 @@ static int dnn_flush_ov(const DNNModel *model) · 74 unmodified lines
9431382 OVModel *ov_model = model->model;
9441383 OVContext *ctx = &ov_model->ctx;
9451384 OVRequestItem *request;
1385+#if HAVE_OPENVINO2
1386+ ov_status_e status;
1387+#else
9461388 IEStatusCode status;
1389+#endif
9471390 int ret;
9481391
9491392 if (ff_queue_size(ov_model->lltask_queue) == 0) {
@@ -962,6 +1405,13 @@ static int dnn_flush_ov(const DNNModel *model) · 12 unmodified lines
9621405 av_log(ctx, AV_LOG_ERROR, "Failed to fill model input.\n");
9631406 return ret;
9641407 }
1408+#if HAVE_OPENVINO2
1409+ status = ov_infer_request_infer(request->infer_request);
1410+ if (status != OK) {
1411+ av_log(ctx, AV_LOG_ERROR, "Failed to start sync inference for OV2\n");
1412+ return ov2_map_error(status, NULL);
1413+ }
1414+#else
9651415 status = ie_infer_set_completion_callback(request->infer_request, &request->callback);
9661416 if (status != OK) {
9671417 av_log(ctx, AV_LOG_ERROR, "Failed to set completion callback for inference\n");
@@ -972,6 +1422,7 @@ static int dnn_flush_ov(const DNNModel *model) · 4 unmodified lines
9721422 av_log(ctx, AV_LOG_ERROR, "Failed to start async inference\n");
9731423 return DNN_GENERIC_ERROR;
9741424 }
1425+#endif
9751426
9761427 return 0;
9771428 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t