FFmpeg
dnn_interface.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Sergey Lavrushkin
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * Implements DNN module initialization with specified backend.
24  */
25 
26 #include "../dnn_interface.h"
27 #include "libavutil/avassert.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/opt.h"
30 
31 #include "libavfilter/filters.h"
32 
34 extern const DNNModule ff_dnn_backend_tf;
35 extern const DNNModule ff_dnn_backend_torch;
36 #if CONFIG_LIBONNXRUNTIME
37 extern const DNNModule ff_dnn_backend_onnx;
38 #endif
39 
40 #define OFFSET(x) offsetof(DnnContext, x)
41 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM
42 static const AVOption dnn_base_options[] = {
43  {"model", "path to model file",
44  OFFSET(model_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS},
45  {"input", "input name of the model",
46  OFFSET(model_inputname), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS},
47  {"output", "output name of the model",
48  OFFSET(model_outputnames_string), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS},
49  {"backend_configs", "backend configs (deprecated)",
50  OFFSET(backend_options), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS | AV_OPT_FLAG_DEPRECATED},
51  {"options", "backend configs (deprecated)",
52  OFFSET(backend_options), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS | AV_OPT_FLAG_DEPRECATED},
53  {"nireq", "number of request",
54  OFFSET(nireq), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
55  {"batch_size", "batch size per request",
56  OFFSET(batch_size), AV_OPT_TYPE_INT, {.i64 = 1}, 1, 1000, FLAGS},
57  {"async", "use DNN async inference",
58  OFFSET(async), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS},
59  {"device", "device to run model",
60  OFFSET(device), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS},
61  {"device_id", "device ID to run model",
62  OFFSET(device_id), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
63  {NULL}
64 };
65 
66 AVFILTER_DEFINE_CLASS(dnn_base);
67 
68 typedef struct DnnBackendInfo {
69  const size_t offset;
70  union {
71  const AVClass *class;
72  const DNNModule *module;
73  };
75 
77  {0, .class = &dnn_base_class},
78  // Must keep the same order as in DNNOptions, so offset value in incremental order
79 #if CONFIG_LIBTENSORFLOW
80  {offsetof(DnnContext, tf_option), .module = &ff_dnn_backend_tf},
81 #endif
82 #if CONFIG_LIBOPENVINO
83  {offsetof(DnnContext, ov_option), .module = &ff_dnn_backend_openvino},
84 #endif
85 #if CONFIG_LIBTORCH
86  {offsetof(DnnContext, torch_option), .module = &ff_dnn_backend_torch},
87 #endif
88 #if CONFIG_LIBONNXRUNTIME
89  {offsetof(DnnContext, onnx_option), .module = &ff_dnn_backend_onnx},
90 #endif
91 };
92 
93 const DNNModule *ff_get_dnn_module(DNNBackendType backend_type, void *log_ctx)
94 {
95  for (int i = 1; i < FF_ARRAY_ELEMS(dnn_backend_info_list); i++) {
96  if (dnn_backend_info_list[i].module->type == backend_type)
98  }
99 
100  av_log(log_ctx, AV_LOG_ERROR,
101  "Module backend_type %d is not supported or enabled.\n",
102  backend_type);
103  return NULL;
104 }
105 
107 {
108  for (int i = 0; i < FF_ARRAY_ELEMS(dnn_backend_info_list); i++) {
109  const AVClass **ptr = (const AVClass **) ((char *) ctx + dnn_backend_info_list[i].offset);
110  *ptr = dnn_backend_info_list[i].class;
111  // Set default values after the class pointer is set
112  av_opt_set_defaults(ptr);
113  }
114 }
115 
116 void *ff_dnn_child_next(DnnContext *obj, void *prev) {
117  size_t pre_offset;
118 
119  if (!prev) {
120  av_assert0(obj->clazz);
121  return obj;
122  }
123 
124  pre_offset = (char *)prev - (char *)obj;
125  for (int i = 0; i < FF_ARRAY_ELEMS(dnn_backend_info_list) - 1; i++) {
126  if (dnn_backend_info_list[i].offset == pre_offset) {
127  const AVClass **ptr = (const AVClass **) ((char *) obj + dnn_backend_info_list[i + 1].offset);
128  av_assert0(*ptr);
129  return ptr;
130  }
131  }
132 
133  return NULL;
134 }
135 
136 const AVClass *ff_dnn_child_class_iterate_with_mask(void **iter, uint32_t backend_mask)
137 {
138  for (uintptr_t i = (uintptr_t)*iter; i < FF_ARRAY_ELEMS(dnn_backend_info_list); i++) {
139  if (i > 0) {
140  const DNNModule *module = dnn_backend_info_list[i].module;
141 
142  if (!(module->type & backend_mask))
143  continue;
144  }
145 
146  *iter = (void *)(i + 1);
147  return dnn_backend_info_list[i].class;
148  }
149 
150  return NULL;
151 }
ff_dnn_backend_openvino
const DNNModule ff_dnn_backend_openvino
DNNModule::type
DNNBackendType type
Definition: dnn_interface.h:190
av_opt_set_defaults
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition: opt.c:1671
opt.h
AVOption
AVOption.
Definition: opt.h:428
filters.h
DnnContext::clazz
const AVClass * clazz
Definition: dnn_interface.h:152
dnn_base_options
static const AVOption dnn_base_options[]
Definition: dnn_interface.c:42
DnnContext
Definition: dnn_interface.h:151
dnn_backend_info_list
static const DnnBackendInfo dnn_backend_info_list[]
Definition: dnn_interface.c:76
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
ff_dnn_backend_onnx
const DNNModule ff_dnn_backend_onnx
Definition: dnn_backend_onnx.c:1096
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
ff_dnn_init_child_class
void ff_dnn_init_child_class(DnnContext *ctx)
Definition: dnn_interface.c:106
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
DnnBackendInfo::offset
const size_t offset
Definition: dnn_interface.c:69
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(dnn_base)
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
DnnBackendInfo::module
const DNNModule * module
Definition: dnn_interface.c:72
NULL
#define NULL
Definition: coverity.c:32
FLAGS
#define FLAGS
Definition: dnn_interface.c:41
DNNBackendType
DNNBackendType
Definition: dnn_interface.h:35
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
DnnBackendInfo
Definition: dnn_interface.c:68
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
ff_get_dnn_module
const DNNModule * ff_get_dnn_module(DNNBackendType backend_type, void *log_ctx)
Definition: dnn_interface.c:93
ff_dnn_backend_tf
const DNNModule ff_dnn_backend_tf
Definition: dnn_backend_tf.c:884
ff_dnn_child_next
void * ff_dnn_child_next(DnnContext *obj, void *prev)
Definition: dnn_interface.c:116
AV_OPT_FLAG_DEPRECATED
#define AV_OPT_FLAG_DEPRECATED
Set if option is deprecated, users should refer to AVOption.help text for more information.
Definition: opt.h:385
ff_dnn_child_class_iterate_with_mask
const AVClass * ff_dnn_child_class_iterate_with_mask(void **iter, uint32_t backend_mask)
Definition: dnn_interface.c:136
ff_dnn_backend_torch
const DNNModule ff_dnn_backend_torch
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
mem.h
DnnBackendInfo::class
const AVClass * class
Definition: dnn_interface.c:71
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:326
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
OFFSET
#define OFFSET(x)
Definition: dnn_interface.c:40
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:275
DNNModule
Definition: dnn_interface.h:188