36#include <tensorflow/c/c_api.h>
67#define OFFSET(x) offsetof(TFOptions, x)
68#define FLAGS AV_OPT_FLAG_FILTERING_PARAM
103 for (uint32_t
i = 0;
i < nb_output; ++
i) {
122 if (!infer_request) {
129 return infer_request;
158 if (TF_GetCode(request->
status) != TF_OK) {
179 TF_DeleteStatus(request->
status);
206 TF_Buffer *graph_buf;
207 unsigned char *graph_data =
NULL;
209 long size, bytes_read;
222 bytes_read =
avio_read(model_file_context, graph_data,
size);
224 if (bytes_read !=
size){
229 graph_buf = TF_NewBuffer();
230 graph_buf->data = graph_data;
231 graph_buf->length =
size;
260 return TF_AllocateTensor(dt, input_dims, 4,
261 input_dims[1] * input_dims[2] * input_dims[3] *
size);
273 tf_output.oper = TF_GraphOperationByName(tf_model->
graph, input_name);
274 if (!tf_output.oper) {
280 dt = TF_OperationOutputType(tf_output);
294 status = TF_NewStatus();
295 TF_GraphGetTensorShape(tf_model->
graph, tf_output, dims, 4, status);
296 if (TF_GetCode(status) != TF_OK){
297 TF_DeleteStatus(status);
301 TF_DeleteStatus(status);
305 for (
int i = 0;
i < 4;
i++)
313 const char *output_name,
int *output_width,
int *output_height)
321 .input_name = input_name,
322 .output_names = &output_name,
356#define SPACE_CHARS " \t\r\n"
368 if (
c >=
'0' &&
c <=
'9')
370 else if (
c >=
'A' &&
c <=
'F')
389 TF_Buffer *graph_def;
390 TF_ImportGraphDefOptions *graph_opts;
391 TF_SessionOptions *sess_opts;
392 const TF_Operation *init_op;
393 uint8_t *sess_config =
NULL;
394 int sess_config_length = 0;
397 if (
ctx->tf_option.sess_config !=
NULL) {
405 if (strncmp(
ctx->tf_option.sess_config,
"0x", 2) != 0) {
409 config =
ctx->tf_option.sess_config + 2;
429 tf_model->
graph = TF_NewGraph();
430 tf_model->
status = TF_NewStatus();
431 graph_opts = TF_NewImportGraphDefOptions();
432 TF_GraphImportGraphDef(tf_model->
graph, graph_def, graph_opts, tf_model->
status);
433 TF_DeleteImportGraphDefOptions(graph_opts);
434 TF_DeleteBuffer(graph_def);
435 if (TF_GetCode(tf_model->
status) != TF_OK){
441 init_op = TF_GraphOperationByName(tf_model->
graph,
"init");
442 sess_opts = TF_NewSessionOptions();
445 TF_SetConfig(sess_opts, sess_config, sess_config_length,tf_model->
status);
447 if (TF_GetCode(tf_model->
status) != TF_OK) {
448 TF_DeleteSessionOptions(sess_opts);
450 ctx->tf_option.sess_config);
456 TF_DeleteSessionOptions(sess_opts);
457 if (TF_GetCode(tf_model->
status) != TF_OK)
470 if (TF_GetCode(tf_model->
status) != TF_OK)
485 if (!model || !*model)
488 tf_model = (
TFModel *)(*model);
510 if (tf_model->
graph){
511 TF_DeleteGraph(tf_model->
graph);
518 TF_DeleteStatus(tf_model->
status);
532 model = &tf_model->
model;
540 if (
ctx->nireq <= 0) {
544#if !HAVE_PTHREAD_CANCEL
556 for (
int i = 0;
i <
ctx->nireq;
i++) {
568 item->
status = TF_NewStatus();
630 if (!infer_request->
tf_input->oper){
773 tf_model = task->
model;
static const AVFilterPad outputs[]
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int avio_open(AVIOContext **s, const char *filename, int flags)
Create and initialize a AVIOContext for accessing the resource indicated by url.
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
#define AVIO_FLAG_READ
read-only
int64_t avio_size(AVIOContext *s)
Get the filesize.
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
#define i(width, name, range_min, range_max)
Misc types and constants that do not belong anywhere else.
int ff_check_exec_params(void *ctx, DNNBackendType backend, DNNFunctionType func_type, DNNExecBaseParams *exec_params)
void ff_dnn_wait_requests(SafeQueue *request_queue, int nireq)
Wait for all inference requests to complete before teardown.
DNNAsyncStatusType ff_dnn_get_result_common(Queue *task_queue, AVFrame **in, AVFrame **out)
Extract input and output frame from the Task Queue after asynchronous inference.
int ff_dnn_async_module_cleanup(DNNAsyncExecModule *async_module)
Join the Async Execution thread and set module pointers to NULL.
int ff_dnn_fill_task(TaskItem *task, DNNExecBaseParams *exec_params, void *backend_model, int async, int do_ioproc)
Fill the Task for Backend Execution.
int ff_dnn_start_inference_async(void *ctx, DNNAsyncExecModule *async_module)
Start asynchronous inference routine for the TensorFlow model on a detached thread.
int ff_dnn_fill_gettingoutput_task(TaskItem *task, DNNExecBaseParams *exec_params, void *backend_model, int input_height, int input_width, void *ctx)
Allocate input and output frames and fill the Task with execution parameters.
DNN common functions different backends.
#define DNN_DEFINE_CLASS(fname)
static void infer_completion_callback(void *args)
static int execute_model_tf(TFRequestItem *request, Queue *lltask_queue)
static int extract_lltask_from_task(TaskItem *task, Queue *lltask_queue)
static TFInferRequest * tf_create_inference_request(void)
Create a TensorFlow inference request.
static int get_output_tf(DNNModel *model, const char *input_name, int input_width, int input_height, const char *output_name, int *output_width, int *output_height)
static void tf_free_request(TFInferRequest *request)
Free the contents of TensorFlow inference request.
static int get_input_tf(DNNModel *model, DNNData *input, const char *input_name)
static int load_tf_model(TFModel *tf_model, const char *model_filename)
static int hex_to_data(uint8_t *data, const char *p)
static DNNAsyncStatusType dnn_get_result_tf(const DNNModel *model, AVFrame **in, AVFrame **out)
static DNNModel * dnn_load_model_tf(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *filter_ctx)
static int tf_start_inference(void *args)
Start synchronous inference for the TensorFlow model.
static int dnn_flush_tf(const DNNModel *model)
static TF_Buffer * read_graph(const char *model_filename)
static const AVOption dnn_tensorflow_options[]
static int dnn_execute_model_tf(const DNNModel *model, DNNExecBaseParams *exec_params)
static TF_Tensor * allocate_input_tensor(const DNNData *input)
const DNNModule ff_dnn_backend_tf
static void destroy_request_item(TFRequestItem **arg)
Free the TFRequestItem completely.
static int fill_model_input_tf(TFModel *tf_model, TFRequestItem *request)
static void infer_completion_callback(void *args)
static void free_buffer(void *data, size_t length)
static void dnn_free_model_tf(DNNModel **model)
static int dnn_get_height_idx_by_layout(DNNLayout layout)
static int dnn_get_width_idx_by_layout(DNNLayout layout)
#define DNN_GENERIC_ERROR
static int dnn_get_channel_idx_by_layout(DNNLayout layout)
int ff_proc_from_frame_to_dnn(AVFrame *frame, DNNData *input, void *log_ctx)
int ff_frame_to_dnn_detect(AVFrame *frame, DNNData *input, void *log_ctx)
int ff_proc_from_dnn_to_frame(AVFrame *frame, DNNData *output, void *log_ctx)
DNN input&output process between AVFrame and DNNData.
@ 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...
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_const int av_toupper(int c)
Locale-independent conversion of ASCII characters to uppercase.
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
void ff_queue_destroy(Queue *q)
Destroy the Queue instance.
void * ff_queue_pop_front(Queue *q)
Remove and free first element from the Queue.
int ff_queue_push_back(Queue *q, void *v)
Add data to the tail of the queue.
void * ff_queue_peek_front(Queue *q)
Return a pointer to the data at the head of the queue.
size_t ff_queue_size(Queue *q)
Return the length of the Queue.
Queue * ff_queue_create(void)
Create a Queue instance.
int ff_safe_queue_push_back(SafeQueue *sq, void *v)
Add data to the tail of queue in the SafeQueue after locking mutex.
void * ff_safe_queue_pop_front(SafeQueue *sq)
Remove and free first element from the queue in SafeQueue.
size_t ff_safe_queue_size(SafeQueue *sq)
Return the length of the SafeQueue.
SafeQueue * ff_safe_queue_create(void)
Create and initialize a SafeQueue instance.
void ff_safe_queue_destroy(SafeQueue *sq)
Destroy the SafeQueue instance.
This structure describes decoded (raw) audio or video data.
Common Async Execution Mechanism for the DNN Backends.
void * args
Argument for the execution functions.
int(* start_inference)(void *request)
Synchronous inference function for the backend with corresponding request item as the argument.
void(* callback)(void *args)
Completion Callback for the backend.
int(* get_input)(struct DNNModel *model, DNNData *input, const char *input_name)
int(* get_output)(struct DNNModel *model, const char *input_name, int input_width, int input_height, const char *output_name, int *output_width, int *output_height)
FramePrePostProc frame_pre_proc
FramePrePostProc frame_post_proc
DetectPostProc detect_post_proc
AVFilterContext * filter_ctx
DNNFunctionType func_type
Linear double-ended data structure.
Double-ended queue with mutex locks ensuring data consistency while multithreading.
Stores execution parameters for single call to the TensorFlow C API.
TF_Tensor ** output_tensors
SafeQueue * request_queue
LastLevelTaskItem * lltask
TFInferRequest * infer_request
DNNAsyncExecModule exec_module
const char ** output_names
#define av_malloc_array(a, b)
static AVFormatContext * ctx
static FilteringContext * filter_ctx