Instead, rely on AV_OPT_TYPE_FLAG_ARRAY, which will automatically perform the parsing.
Unified · Split
| @@ -31,6 +31,7 @@ · 30 unmodified lines | |||
| 31 | #include "libavutil/avstring.h" | 31 | #include "libavutil/avstring.h" |
| 32 | #include "libavutil/detection_bbox.h" | 32 | #include "libavutil/detection_bbox.h" |
| 33 | #include "libavutil/fifo.h" | 33 | #include "libavutil/fifo.h" |
| 34 | #include <float.h> | ||
| 34 | 35 | ||
| 35 | typedef enum { | 36 | typedef enum { |
| 36 | DDMT_SSD, | 37 | DDMT_SSD, |
| @@ -53,11 +54,12 @@ typedef struct DnnDetectContext { · 16 unmodified lines | |||
| 53 | AVFifo *bboxes_fifo; | 54 | AVFifo *bboxes_fifo; |
| 54 | int scale_width; | 55 | int scale_width; |
| 55 | int scale_height; | 56 | int scale_height; |
| 56 | char *anchors_str; | ||
| 57 | float *anchors; | 57 | float *anchors; |
| 58 | int nb_anchor; | 58 | int nb_anchor; |
| 59 | } DnnDetectContext; | 59 | } DnnDetectContext; |
| 60 | 60 | ||
| 61 | static const AVOptionArrayDef anchor_array_def = { .sep = '&' }; | ||
| 62 | |||
| 61 | #define OFFSET(x) offsetof(DnnDetectContext, dnnctx.x) | 63 | #define OFFSET(x) offsetof(DnnDetectContext, dnnctx.x) |
| 62 | #define OFFSET2(x) offsetof(DnnDetectContext, x) | 64 | #define OFFSET2(x) offsetof(DnnDetectContext, x) |
| 63 | #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM | 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 | { "cell_w", "cell width", OFFSET2(cell_w), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INTMAX_MAX, FLAGS }, | 81 | { "cell_w", "cell width", OFFSET2(cell_w), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INTMAX_MAX, FLAGS }, |
| 80 | { "cell_h", "cell height", OFFSET2(cell_h), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INTMAX_MAX, FLAGS }, | 82 | { "cell_h", "cell height", OFFSET2(cell_h), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INTMAX_MAX, FLAGS }, |
| 81 | { "nb_classes", "The number of class", OFFSET2(nb_classes), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INTMAX_MAX, FLAGS }, | 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 | { NULL } | 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 | return label_id; | 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 | /* Calculate Intersection Over Union */ | 111 | /* Calculate Intersection Over Union */ |
| 138 | static float dnn_detect_IOU(AVDetectionBBox *bbox1, AVDetectionBBox *bbox2) | 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 | return 0; | 678 | return 0; |
| 714 | } | 679 | } |
| 715 | 680 | ||