Instead, rely on AV_OPT_TYPE_FLAG_ARRAY, which will automatically perform the parsing.
Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include "libavutil/avstring.h" |
| 32 | 32 | #include "libavutil/detection_bbox.h" |
| 33 | 33 | #include "libavutil/fifo.h" |
| 34 | +#include <float.h> | |
| 34 | 35 | |
| 35 | 36 | typedef enum { |
| 36 | 37 | DDMT_SSD, |
| @@ -53,11 +54,12 @@ typedef struct DnnDetectContext { · 16 unmodified lines | ||
| 53 | 54 | AVFifo *bboxes_fifo; |
| 54 | 55 | int scale_width; |
| 55 | 56 | int scale_height; |
| 56 | − char *anchors_str; | |
| 57 | 57 | float *anchors; |
| 58 | 58 | int nb_anchor; |
| 59 | 59 | } DnnDetectContext; |
| 60 | 60 | |
| 61 | +static const AVOptionArrayDef anchor_array_def = { .sep = '&' }; | |
| 62 | + | |
| 61 | 63 | #define OFFSET(x) offsetof(DnnDetectContext, dnnctx.x) |
| 62 | 64 | #define OFFSET2(x) offsetof(DnnDetectContext, x) |
| 63 | 65 | #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
| @@ -79,7 +81,7 @@ static const AVOption dnn_detect_options[] = { · 15 unmodified lines | ||
| 79 | 81 | { "cell_w", "cell width", OFFSET2(cell_w), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INTMAX_MAX, FLAGS }, |
| 80 | 82 | { "cell_h", "cell height", OFFSET2(cell_h), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INTMAX_MAX, FLAGS }, |
| 81 | 83 | { "nb_classes", "The number of class", OFFSET2(nb_classes), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INTMAX_MAX, FLAGS }, |
| 82 | − { "anchors", "anchors, splited by '&'", OFFSET2(anchors_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, | |
| 84 | + { "anchors", "anchors, splited by '&'", OFFSET2(anchors), AV_OPT_TYPE_FLOAT | AV_OPT_TYPE_FLAG_ARRAY, { .arr = &anchor_array_def }, FLT_MIN, FLT_MAX, FLAGS }, | |
| 83 | 85 | { NULL } |
| 84 | 86 | }; |
| 85 | 87 | |
| @@ -106,34 +108,6 @@ static int dnn_detect_get_label_id(int nb_classes, int cell_size, float *label_d · 20 unmodified lines | ||
| 106 | 108 | return label_id; |
| 107 | 109 | } |
| 108 | 110 | |
| 109 | −static int dnn_detect_parse_anchors(char *anchors_str, float **anchors) | |
| 110 | −{ | |
| 111 | − char *saveptr = NULL, *token; | |
| 112 | − float *anchors_buf; | |
| 113 | − int nb_anchor = 0, i = 0; | |
| 114 | − while(anchors_str[i] != '\0') { | |
| 115 | − if(anchors_str[i] == '&') | |
| 116 | − nb_anchor++; | |
| 117 | − i++; | |
| 118 | − } | |
| 119 | − nb_anchor++; | |
| 120 | − anchors_buf = av_mallocz(nb_anchor * sizeof(**anchors)); | |
| 121 | − if (!anchors_buf) { | |
| 122 | − return 0; | |
| 123 | − } | |
| 124 | − for (int i = 0; i < nb_anchor; i++) { | |
| 125 | − token = av_strtok(anchors_str, "&", &saveptr); | |
| 126 | − if (!token) { | |
| 127 | − av_freep(&anchors_buf); | |
| 128 | − return 0; | |
| 129 | − } | |
| 130 | − anchors_buf[i] = strtof(token, NULL); | |
| 131 | − anchors_str = NULL; | |
| 132 | − } | |
| 133 | − *anchors = anchors_buf; | |
| 134 | − return nb_anchor; | |
| 135 | −} | |
| 136 | − | |
| 137 | 111 | /* Calculate Intersection Over Union */ |
| 138 | 112 | static float dnn_detect_IOU(AVDetectionBBox *bbox1, AVDetectionBBox *bbox2) |
| 139 | 113 | { |
| @@ -701,15 +675,6 @@ static av_cold int dnn_detect_init(AVFilterContext *context) · 561 unmodified lines | ||
| 701 | 675 | } |
| 702 | 676 | } |
| 703 | 677 | |
| 704 | − if (ctx->anchors_str) { | |
| 705 | − ret = dnn_detect_parse_anchors(ctx->anchors_str, &ctx->anchors); | |
| 706 | − if (!ctx->anchors) { | |
| 707 | − av_log(context, AV_LOG_ERROR, "failed to parse anchors_str\n"); | |
| 708 | − return AVERROR(EINVAL); | |
| 709 | − } | |
| 710 | − ctx->nb_anchor = ret; | |
| 711 | − } | |
| 712 | − | |
| 713 | 678 | return 0; |
| 714 | 679 | } |
| 715 | 680 | |