diff --git a/configure b/configure
index ae9ba7729ab502a0fb2ee4ea7580b534ca794898..ff9670db9ee9d0fc18c97b127fc0a305debe73f9 100755
--- a/configure
+++ b/configure
@@ -1186,7 +1186,6 @@ HAVE_LIST="
     setrlimit
     strerror_r
     strptime
-    strtok_r
     struct_addrinfo
     struct_ipv6_mreq
     struct_sockaddr_in6
@@ -1585,17 +1584,14 @@ tcp_protocol_deps="network"
 udp_protocol_deps="network"
 
 # filters
-abuffer_filter_deps="strtok_r"
-aconvert_filter_deps="strtok_r"
-aformat_filter_deps="strtok_r"
 amovie_filter_deps="avcodec avformat"
 blackframe_filter_deps="gpl"
 boxblur_filter_deps="gpl"
 cropdetect_filter_deps="gpl"
 delogo_filter_deps="gpl"
 drawtext_filter_deps="libfreetype"
-frei0r_filter_deps="frei0r dlopen strtok_r"
-frei0r_src_filter_deps="frei0r dlopen strtok_r"
+frei0r_filter_deps="frei0r dlopen"
+frei0r_src_filter_deps="frei0r dlopen"
 hqdn3d_filter_deps="gpl"
 movie_filter_deps="avcodec avformat"
 mp_filter_deps="gpl avcodec"
@@ -2942,7 +2938,6 @@ check_func  ${malloc_prefix}posix_memalign      && enable posix_memalign
 check_func  setrlimit
 check_func  strerror_r
 check_func  strptime
-check_func  strtok_r
 check_func_headers conio.h kbhit
 check_func_headers windows.h PeekNamedPipe
 check_func_headers io.h setmode
diff --git a/libavfilter/af_aconvert.c b/libavfilter/af_aconvert.c
index d794c23576c169e4618d9073aacd231d420da30b..fef096cb8e8bffe179fa6c0457df76e13fd58b25 100644
--- a/libavfilter/af_aconvert.c
+++ b/libavfilter/af_aconvert.c
@@ -28,6 +28,7 @@
  */
 
 #include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
 #include "libavcodec/audioconvert.h"
 #include "avfilter.h"
 #include "internal.h"
@@ -125,15 +126,15 @@ static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
     aconvert->out_chlayout    = 0;
     aconvert->out_packing_fmt = -1;
 
-    if ((arg = strtok_r(args, ":", &ptr)) && strcmp(arg, "auto")) {
+    if ((arg = av_strtok(args, ":", &ptr)) && strcmp(arg, "auto")) {
         if ((ret = ff_parse_sample_format(&aconvert->out_sample_fmt, arg, ctx)) < 0)
             goto end;
     }
-    if ((arg = strtok_r(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
+    if ((arg = av_strtok(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
         if ((ret = ff_parse_channel_layout(&aconvert->out_chlayout, arg, ctx)) < 0)
             goto end;
     }
-    if ((arg = strtok_r(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
+    if ((arg = av_strtok(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
         if ((ret = ff_parse_packing_format((int *)&aconvert->out_packing_fmt, arg, ctx)) < 0)
             goto end;
     }
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
index a7aa45f0b18b1752f3c142b70fed19ef02e6e25a..20ab940cc83cfa93b6645f64b1a4fa9f31e65c67 100644
--- a/libavfilter/af_aformat.c
+++ b/libavfilter/af_aformat.c
@@ -50,7 +50,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
         aformat->fmts_list = all_formats;                               \
     } else {                                                            \
         for (fmt_str = fmts_str;                                        \
-             fmt_str = strtok_r(fmt_str, ",", &ptr); fmt_str = NULL) {  \
+             fmt_str = av_strtok(fmt_str, ",", &ptr); fmt_str = NULL) { \
             if ((ret = ff_parse_##fmt_name((fmt_type *)&fmt,            \
                                            fmt_str, ctx)) < 0) {        \
                 av_freep(&fmts_str);                                    \
diff --git a/libavfilter/asrc_abuffer.c b/libavfilter/asrc_abuffer.c
index 4a0f08e538d95fd81b5b2b8075c409b3380ad163..bfa7e63f2a00dcf7e2fc566dfe9416f3cb904f48 100644
--- a/libavfilter/asrc_abuffer.c
+++ b/libavfilter/asrc_abuffer.c
@@ -25,6 +25,7 @@
  */
 
 #include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
 #include "libavutil/fifo.h"
 #include "asrc_abuffer.h"
 #include "internal.h"
@@ -256,7 +257,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
     char *args = av_strdup(args0);
     int ret;
 
-    arg = strtok_r(args, ":", &ptr);
+    arg = av_strtok(args, ":", &ptr);
 
 #define ADD_FORMAT(fmt_name)                                            \
     if (!arg)                                                           \
@@ -266,7 +267,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
         return ret;                                                     \
     }                                                                   \
     if (*args)                                                          \
-        arg = strtok_r(NULL, ":", &ptr)
+        arg = av_strtok(NULL, ":", &ptr)
 
     ADD_FORMAT(sample_rate);
     ADD_FORMAT(sample_format);
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index f5b7abb54302d2dd1eab7f2f7efe1de1066af749..5d5a4db1e678d523d79d9903cb66a7a79f43afad 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -216,7 +216,7 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
     /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */
     if ((path = av_strdup(getenv("FREI0R_PATH")))) {
         char *p, *ptr = NULL;
-        for (p = path; p = strtok_r(p, ":", &ptr); p = NULL)
+        for (p = path; p = av_strtok(p, ":", &ptr); p = NULL)
             if (frei0r->dl_handle = load_path(ctx, p, dl_name))
                 break;
         av_free(path);
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index 4c504482da61661f48287775502a93567af86200..247cd71745d63b07ec8561213bd7d103e18232ff 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -160,6 +160,35 @@ char *av_get_token(const char **buf, const char *term)
     return ret;
 }
 
+char *av_strtok(char *s, const char *delim, char **saveptr)
+{
+    char *tok;
+
+    if (!s && !(s = *saveptr))
+        return NULL;
+
+    /* skip leading delimiters */
+    s += strspn(s, delim);
+
+    /* s now points to the first non delimiter char, or to the end of the string */
+    if (!*s) {
+        *saveptr = NULL;
+        return NULL;
+    }
+    tok = s++;
+
+    /* skip non delimiters */
+    s += strcspn(s, delim);
+    if (*s) {
+        *s = 0;
+        *saveptr = s+1;
+    } else {
+        *saveptr = NULL;
+    }
+
+    return tok;
+}
+
 #ifdef TEST
 
 #undef printf
diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index 2be84a9ed09e34950d9d46edd1931ffd7f495a4e..0b2205a9be59cc351c2bc4d22535d4bac6b4d866 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -141,4 +141,28 @@ char *av_d2str(double d);
  */
 char *av_get_token(const char **buf, const char *term);
 
+/**
+ * Split the string into several tokens which can be accessed by
+ * successive calls to av_strtok().
+ *
+ * A token is defined as a sequence of characters not belonging to the
+ * set specified in delim.
+ *
+ * On the first call to av_strtok(), s should point to the string to
+ * parse, and the value of saveptr is ignored. In subsequent calls, s
+ * should be NULL, and saveptr should be unchanged since the previous
+ * call.
+ *
+ * This function is similar to strtok_r() defined in POSIX.1.
+ *
+ * @param s the string to parse, may be NULL
+ * @param delim 0-terminated list of token delimiters, must be non-NULL
+ * @param saveptr user-provided pointer which points to stored
+ * information necessary for av_strtok() to continue scanning the same
+ * string. saveptr is updated to point to the next character after the
+ * first delimiter found, or to NULL if the string was terminated
+ * @return the found token, or NULL when no token is found
+ */
+char *av_strtok(char *s, const char *delim, char **saveptr);
+
 #endif /* AVUTIL_AVSTRING_H */