From 6506ab8b03dd6747f6ad6b836a347a6fc346708b Mon Sep 17 00:00:00 2001 From: "Xie, Lin" Date: Mon, 9 Nov 2020 14:09:13 +0800 Subject: [PATCH] dnn/queue: add queue and safe_queue support Signed-off-by: Xie, Lin Signed-off-by: Wu Zhiwen Signed-off-by: Guo, Yejun --- libavfilter/dnn/Makefile | 2 + libavfilter/dnn/queue.c | 176 +++++++++++++++++++++++++++++++++++ libavfilter/dnn/queue.h | 41 ++++++++ libavfilter/dnn/safe_queue.c | 92 ++++++++++++++++++ libavfilter/dnn/safe_queue.h | 36 +++++++ 5 files changed, 347 insertions(+) create mode 100644 libavfilter/dnn/queue.c create mode 100644 libavfilter/dnn/queue.h create mode 100644 libavfilter/dnn/safe_queue.c create mode 100644 libavfilter/dnn/safe_queue.h diff --git a/libavfilter/dnn/Makefile b/libavfilter/dnn/Makefile index b0b76301ec..d6d58f4b61 100644 --- a/libavfilter/dnn/Makefile +++ b/libavfilter/dnn/Makefile @@ -1,5 +1,7 @@ OBJS-$(CONFIG_DNN) += dnn/dnn_interface.o OBJS-$(CONFIG_DNN) += dnn/dnn_io_proc.o +OBJS-$(CONFIG_DNN) += dnn/queue.o +OBJS-$(CONFIG_DNN) += dnn/safe_queue.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layers.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_avgpool.o diff --git a/libavfilter/dnn/queue.c b/libavfilter/dnn/queue.c new file mode 100644 index 0000000000..0a07c5473d --- /dev/null +++ b/libavfilter/dnn/queue.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "queue.h" +#include "libavutil/mem.h" +#include "libavutil/avassert.h" + +typedef struct _queue_entry queue_entry; + +typedef struct _queue { + queue_entry *head; + queue_entry *tail; + size_t length; +}queue; + +typedef struct _queue_entry { + void *value; + queue_entry *prev; + queue_entry *next; +} queue_entry; + +static inline queue_entry *create_entry(void *val) +{ + queue_entry *entry = av_malloc(sizeof(*entry)); + av_assert0(entry != NULL); + entry->value = val; + return entry; +} + +queue* queue_create(void) +{ + queue *q = av_malloc(sizeof(*q)); + if (!q) + return NULL; + + q->head = create_entry(q); + q->tail = create_entry(q); + q->head->next = q->tail; + q->tail->prev = q->head; + q->head->prev = NULL; + q->tail->next = NULL; + q->length = 0; + + return q; +} + +void queue_destroy(queue *q) +{ + queue_entry *entry; + if (!q) + return; + + entry = q->head; + while (entry != NULL) { + queue_entry *temp = entry; + entry = entry->next; + av_freep(&temp); + } + + av_freep(&q); +} + +size_t queue_size(queue *q) +{ + return q ? q->length : 0; +} + +void *queue_peek_front(queue *q) +{ + if (!q || q->length == 0) + return NULL; + + return q->head->next->value; +} + +void *queue_peek_back(queue *q) +{ + if (!q || q->length == 0) + return NULL; + + return q->tail->prev->value; +} + +void queue_push_front(queue *q, void *v) +{ + queue_entry *new_entry; + queue_entry *original_next; + if (!q) + return; + + new_entry = create_entry(v); + original_next = q->head->next; + + q->head->next = new_entry; + original_next->prev = new_entry; + new_entry->prev = q->head; + new_entry->next = original_next; + q->length++; +} + +void queue_push_back(queue *q, void *v) +{ + queue_entry *new_entry; + queue_entry *original_prev; + if (!q) + return; + + new_entry = create_entry(v); + original_prev = q->tail->prev; + + q->tail->prev = new_entry; + original_prev->next = new_entry; + new_entry->next = q->tail; + new_entry->prev = original_prev; + q->length++; +} + +void *queue_pop_front(queue *q) +{ + queue_entry *front; + queue_entry *new_head_next; + void *ret; + + if (!q || q->length == 0) + return NULL; + + front = q->head->next; + new_head_next = front->next; + ret = front->value; + + q->head->next = new_head_next; + new_head_next->prev = q->head; + + av_freep(&front); + q->length--; + return ret; +} + +void *queue_pop_back(queue *q) +{ + queue_entry *back; + queue_entry *new_tail_prev; + void *ret; + + if (!q || q->length == 0) + return NULL; + + back = q->tail->prev; + new_tail_prev = back->prev; + ret = back->value; + + q->tail->prev = new_tail_prev; + new_tail_prev->next = q->tail; + + av_freep(&back); + q->length--; + return ret; +} diff --git a/libavfilter/dnn/queue.h b/libavfilter/dnn/queue.h new file mode 100644 index 0000000000..75f42f403b --- /dev/null +++ b/libavfilter/dnn/queue.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVFILTER_DNN_QUEUE_H +#define AVFILTER_DNN_QUEUE_H + +typedef struct _queue queue; + +queue *queue_create(void); +void queue_destroy(queue *q); + +size_t queue_size(queue *q); + +void *queue_peek_front(queue *q); +void *queue_peek_back(queue *q); + +void queue_push_front(queue *q, void *v); +void queue_push_back(queue *q, void *v); + +void *queue_pop_front(queue *q); +void *queue_pop_back(queue *q); + +#endif diff --git a/libavfilter/dnn/safe_queue.c b/libavfilter/dnn/safe_queue.c new file mode 100644 index 0000000000..dba2e0fbbc --- /dev/null +++ b/libavfilter/dnn/safe_queue.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "queue.h" +#include "safe_queue.h" +#include "libavutil/mem.h" +#include "libavutil/avassert.h" +#include "libavutil/thread.h" + +typedef struct _safe_queue { + queue *q; + pthread_mutex_t mutex; + pthread_cond_t cond; +}safe_queue; + +safe_queue *safe_queue_create(void) +{ + safe_queue *sq = av_malloc(sizeof(*sq)); + if (!sq) + return NULL; + + sq->q = queue_create(); + if (!sq->q) + return NULL; + + pthread_mutex_init(&sq->mutex, NULL); + pthread_cond_init(&sq->cond, NULL); + return sq; +} + +void safe_queue_destroy(safe_queue *sq) +{ + if (!sq) + return; + + queue_destroy(sq->q); + pthread_mutex_destroy(&sq->mutex); + pthread_cond_destroy(&sq->cond); + av_freep(&sq); +} + +size_t safe_queue_size(safe_queue *sq) +{ + return sq ? queue_size(sq->q) : 0; +} + +void safe_queue_push_front(safe_queue *sq, void *v) +{ + pthread_mutex_lock(&sq->mutex); + queue_push_front(sq->q, v); + pthread_cond_signal(&sq->cond); + pthread_mutex_unlock(&sq->mutex); +} + +void safe_queue_push_back(safe_queue *sq, void *v) +{ + pthread_mutex_lock(&sq->mutex); + queue_push_back(sq->q, v); + pthread_cond_signal(&sq->cond); + pthread_mutex_unlock(&sq->mutex); +} + +void *safe_queue_pop_front(safe_queue *sq) +{ + void *value; + pthread_mutex_lock(&sq->mutex); + while (queue_size(sq->q) == 0) { + pthread_cond_wait(&sq->cond, &sq->mutex); + } + value = queue_pop_front(sq->q); + pthread_cond_signal(&sq->cond); + pthread_mutex_unlock(&sq->mutex); + return value; +} diff --git a/libavfilter/dnn/safe_queue.h b/libavfilter/dnn/safe_queue.h new file mode 100644 index 0000000000..aaa15fadf2 --- /dev/null +++ b/libavfilter/dnn/safe_queue.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_DNN_SAFE_QUEUE_H +#define AVFILTER_DNN_SAFE_QUEUE_H + +typedef struct _safe_queue safe_queue; + +safe_queue *safe_queue_create(void); +void safe_queue_destroy(safe_queue *sq); + +size_t safe_queue_size(safe_queue *sq); + +void safe_queue_push_front(safe_queue *sq, void *v); +void safe_queue_push_back(safe_queue *sq, void *v); + +void *safe_queue_pop_front(safe_queue *sq); + +#endif