diff --git a/doc/APIchanges b/doc/APIchanges
index f2830968bb..ae1f9ace77 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,11 @@ libavutil:     2017-10-21
 
 API changes, most recent first:
 
+2020-10-xx - xxxxxxxxxx - lavd 58.12.100 - avdevice.h
+  Deprecate use of av_input_audio_device_next(), av_input_video_device_next(),
+  av_output_audio_device_next(), av_output_video_device_next().
+  Add av_indev_iterate(), and av_outdev_iterate().
+
 2020-xx-xx - xxxxxxxxxx - lavu 56.60.100 - buffer.h
   Add a av_buffer_replace() convenience function.
 
diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
index 4137f60109..2f17e9f33b 100644
--- a/libavdevice/alldevices.c
+++ b/libavdevice/alldevices.c
@@ -63,11 +63,32 @@ extern AVInputFormat  ff_libdc1394_demuxer;
 #include "libavdevice/outdev_list.c"
 #include "libavdevice/indev_list.c"
 
+const AVOutputFormat *av_outdev_iterate(void **opaque)
+{
+    uintptr_t i = (uintptr_t)*opaque;
+    const AVOutputFormat *f = outdev_list[i];
+
+    if (f)
+        *opaque = (void*)(i + 1);
+    return f;
+}
+
+const AVInputFormat *av_indev_iterate(void **opaque)
+{
+    uintptr_t i = (uintptr_t)*opaque;
+    const AVInputFormat *f = indev_list[i];
+
+    if (f)
+        *opaque = (void*)(i + 1);
+    return f;
+}
+
 void avdevice_register_all(void)
 {
     avpriv_register_devices(outdev_list, indev_list);
 }
 
+#if FF_API_DEVICE_NEXT
 static void *next_input(AVInputFormat *prev, AVClassCategory c2)
 {
     const AVClass *pc;
@@ -143,3 +164,4 @@ AVOutputFormat *av_output_video_device_next(AVOutputFormat *d)
 {
     return next_output(d, AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT);
 }
+#endif
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index ee9462480e..388f93c155 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -70,13 +70,39 @@ const char *avdevice_license(void);
  */
 void avdevice_register_all(void);
 
+/**
+ * Iterate over all registered output devices.
+ *
+ * @param opaque a pointer where libavdevice will store the iteration state. Must
+ *               point to NULL to start the iteration.
+ *
+ * @return the next registered output device or NULL when the iteration is
+ *         finished
+ */
+const AVOutputFormat *av_outdev_iterate(void **opaque);
+
+/**
+ * Iterate over all registered input devices.
+ *
+ * @param opaque a pointer where libavdevice will store the iteration state. Must
+ *               point to NULL to start the iteration.
+ *
+ * @return the next registered input device or NULL when the iteration is
+ *         finished
+ */
+const AVInputFormat *av_indev_iterate(void **opaque);
+
+#if FF_API_DEVICE_NEXT
 /**
  * Audio input devices iterator.
  *
  * If d is NULL, returns the first registered input audio/video device,
  * if d is non-NULL, returns the next registered input audio/video device after d
  * or NULL if d is the last one.
+ *
+ * @deprecated use av_indev_iterate() instead
  */
+attribute_deprecated
 AVInputFormat *av_input_audio_device_next(AVInputFormat  *d);
 
 /**
@@ -85,7 +111,10 @@ AVInputFormat *av_input_audio_device_next(AVInputFormat  *d);
  * If d is NULL, returns the first registered input audio/video device,
  * if d is non-NULL, returns the next registered input audio/video device after d
  * or NULL if d is the last one.
+ *
+ * @deprecated use av_indev_iterate() instead
  */
+attribute_deprecated
 AVInputFormat *av_input_video_device_next(AVInputFormat  *d);
 
 /**
@@ -94,7 +123,10 @@ AVInputFormat *av_input_video_device_next(AVInputFormat  *d);
  * If d is NULL, returns the first registered output audio/video device,
  * if d is non-NULL, returns the next registered output audio/video device after d
  * or NULL if d is the last one.
+ *
+ * @deprecated use av_outdev_iterate() instead
  */
+attribute_deprecated
 AVOutputFormat *av_output_audio_device_next(AVOutputFormat *d);
 
 /**
@@ -103,8 +135,12 @@ AVOutputFormat *av_output_audio_device_next(AVOutputFormat *d);
  * If d is NULL, returns the first registered output audio/video device,
  * if d is non-NULL, returns the next registered output audio/video device after d
  * or NULL if d is the last one.
+ *
+ * @deprecated use av_outdev_iterate() instead
  */
+attribute_deprecated
 AVOutputFormat *av_output_video_device_next(AVOutputFormat *d);
+#endif
 
 typedef struct AVDeviceRect {
     int x;      /**< x coordinate of top left corner */
diff --git a/libavdevice/version.h b/libavdevice/version.h
index e3aca9e3d2..7f5f46e428 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -28,8 +28,8 @@
 #include "libavutil/version.h"
 
 #define LIBAVDEVICE_VERSION_MAJOR  58
-#define LIBAVDEVICE_VERSION_MINOR  11
-#define LIBAVDEVICE_VERSION_MICRO 102
+#define LIBAVDEVICE_VERSION_MINOR  12
+#define LIBAVDEVICE_VERSION_MICRO 100
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
                                                LIBAVDEVICE_VERSION_MINOR, \
@@ -46,5 +46,8 @@
  * dropped at a future version bump. The defines themselves are not part of
  * the public API and may change, break or disappear at any time.
  */
+#ifndef FF_API_DEVICE_NEXT
+#define FF_API_DEVICE_NEXT              (LIBAVDEVICE_VERSION_MAJOR < 60)
+#endif
 
 #endif /* AVDEVICE_VERSION_H */
