[FFmpeg-devel,v4,2/7] lavf/rtp: replace linked list with array

Submitted by Josh de Kock on Feb. 2, 2018, 7:44 p.m.

Details

Message ID 1517600658-32681-2-git-send-email-josh@itanimul.li
State New
Headers show

Commit Message

Josh de Kock Feb. 2, 2018, 7:44 p.m.
---
 libavformat/allformats.c |   4 --
 libavformat/rdt.c        |   9 +---
 libavformat/rdt.h        |   5 --
 libavformat/rtpdec.c     | 138 ++++++++++++++++++++++++++---------------------
 libavformat/rtpdec.h     |  25 +++++++--
 5 files changed, 100 insertions(+), 81 deletions(-)

Comments

Muhammad Faiz Feb. 4, 2018, 1:43 p.m.
On Sat, Feb 3, 2018 at 2:44 AM, Josh de Kock <josh@itanimul.li> wrote:
> ---
>  libavformat/allformats.c |   4 --
>  libavformat/rdt.c        |   9 +---
>  libavformat/rdt.h        |   5 --
>  libavformat/rtpdec.c     | 138 ++++++++++++++++++++++++++---------------------
>  libavformat/rtpdec.h     |  25 +++++++--
>  5 files changed, 100 insertions(+), 81 deletions(-)
>
> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> index ec84096..83ed766 100644
> --- a/libavformat/allformats.c
> +++ b/libavformat/allformats.c
> @@ -282,10 +282,6 @@ static void register_all(void)
>      REGISTER_DEMUXER (SDR2,             sdr2);
>      REGISTER_DEMUXER (SDS,              sds);
>      REGISTER_DEMUXER (SDX,              sdx);
> -#if CONFIG_RTPDEC
> -    ff_register_rtp_dynamic_payload_handlers();
> -    ff_register_rdt_dynamic_payload_handlers();
> -#endif
>      REGISTER_DEMUXER (SEGAFILM,         segafilm);
>      REGISTER_MUXER   (SEGMENT,          segment);
>      REGISTER_MUXER   (SEGMENT,          stream_segment);
> diff --git a/libavformat/rdt.c b/libavformat/rdt.c
> index b69827f..31a32ff 100644
> --- a/libavformat/rdt.c
> +++ b/libavformat/rdt.c
> @@ -554,7 +554,7 @@ rdt_close_context (PayloadContext *rdt)
>  }
>
>  #define RDT_HANDLER(n, s, t) \
> -static RTPDynamicProtocolHandler rdt_ ## n ## _handler = { \
> +RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \
>      .enc_name         = s, \
>      .codec_type       = t, \
>      .codec_id         = AV_CODEC_ID_NONE, \
> @@ -570,10 +570,3 @@ RDT_HANDLER(live_audio, "x-pn-multirate-realaudio-live", AVMEDIA_TYPE_AUDIO);
>  RDT_HANDLER(video,      "x-pn-realvideo",                AVMEDIA_TYPE_VIDEO);
>  RDT_HANDLER(audio,      "x-pn-realaudio",                AVMEDIA_TYPE_AUDIO);
>
> -void ff_register_rdt_dynamic_payload_handlers(void)
> -{
> -    ff_register_dynamic_payload_handler(&rdt_video_handler);
> -    ff_register_dynamic_payload_handler(&rdt_audio_handler);
> -    ff_register_dynamic_payload_handler(&rdt_live_video_handler);
> -    ff_register_dynamic_payload_handler(&rdt_live_audio_handler);
> -}
> diff --git a/libavformat/rdt.h b/libavformat/rdt.h
> index ce6026f..2480565 100644
> --- a/libavformat/rdt.h
> +++ b/libavformat/rdt.h
> @@ -60,11 +60,6 @@ void ff_rdt_calc_response_and_checksum(char response[41], char chksum[9],
>                                         const char *challenge);
>
>  /**
> - * Register RDT-related dynamic payload handlers with our cache.
> - */
> -void ff_register_rdt_dynamic_payload_handlers(void);
> -
> -/**
>   * Add subscription information to Subscribe parameter string.
>   *
>   * @param cmd string to write the subscription information into.
> diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
> index 4acb1ca..6499e27 100644
> --- a/libavformat/rtpdec.c
> +++ b/libavformat/rtpdec.c
> @@ -69,88 +69,104 @@ static RTPDynamicProtocolHandler t140_dynamic_handler = { /* RFC 4103 */
>      .codec_id   = AV_CODEC_ID_TEXT,
>  };
>
> -static RTPDynamicProtocolHandler *rtp_first_dynamic_payload_handler = NULL;
> +extern RTPDynamicProtocolHandler ff_rdt_video_handler;
> +extern RTPDynamicProtocolHandler ff_rdt_audio_handler;
> +extern RTPDynamicProtocolHandler ff_rdt_live_video_handler;
> +extern RTPDynamicProtocolHandler ff_rdt_live_audio_handler;
> +
> +static const RTPDynamicProtocolHandler *rtp_dynamic_protocol_handler_list[] = {
> +    /* rtp */
> +    &ff_ac3_dynamic_handler,
> +    &ff_amr_nb_dynamic_handler,
> +    &ff_amr_wb_dynamic_handler,
> +    &ff_dv_dynamic_handler,
> +    &ff_g726_16_dynamic_handler,
> +    &ff_g726_24_dynamic_handler,
> +    &ff_g726_32_dynamic_handler,
> +    &ff_g726_40_dynamic_handler,
> +    &ff_g726le_16_dynamic_handler,
> +    &ff_g726le_24_dynamic_handler,
> +    &ff_g726le_32_dynamic_handler,
> +    &ff_g726le_40_dynamic_handler,
> +    &ff_h261_dynamic_handler,
> +    &ff_h263_1998_dynamic_handler,
> +    &ff_h263_2000_dynamic_handler,
> +    &ff_h263_rfc2190_dynamic_handler,
> +    &ff_h264_dynamic_handler,
> +    &ff_hevc_dynamic_handler,
> +    &ff_ilbc_dynamic_handler,
> +    &ff_jpeg_dynamic_handler,
> +    &ff_mp4a_latm_dynamic_handler,
> +    &ff_mp4v_es_dynamic_handler,
> +    &ff_mpeg_audio_dynamic_handler,
> +    &ff_mpeg_audio_robust_dynamic_handler,
> +    &ff_mpeg_video_dynamic_handler,
> +    &ff_mpeg4_generic_dynamic_handler,
> +    &ff_mpegts_dynamic_handler,
> +    &ff_ms_rtp_asf_pfa_handler,
> +    &ff_ms_rtp_asf_pfv_handler,
> +    &ff_qcelp_dynamic_handler,
> +    &ff_qdm2_dynamic_handler,
> +    &ff_qt_rtp_aud_handler,
> +    &ff_qt_rtp_vid_handler,
> +    &ff_quicktime_rtp_aud_handler,
> +    &ff_quicktime_rtp_vid_handler,
> +    &ff_rfc4175_rtp_handler,
> +    &ff_svq3_dynamic_handler,
> +    &ff_theora_dynamic_handler,
> +    &ff_vc2hq_dynamic_handler,
> +    &ff_vorbis_dynamic_handler,
> +    &ff_vp8_dynamic_handler,
> +    &ff_vp9_dynamic_handler,
> +    &gsm_dynamic_handler,
> +    &l24_dynamic_handler,
> +    &opus_dynamic_handler,
> +    &realmedia_mp3_dynamic_handler,
> +    &speex_dynamic_handler,
> +    &t140_dynamic_handler,
> +    /* rdt */
> +    &ff_rdt_video_handler,
> +    &ff_rdt_audio_handler,
> +    &ff_rdt_live_video_handler,
> +    &ff_rdt_live_audio_handler,
> +    NULL,
> +};
>
> -void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
> +const RTPDynamicProtocolHandler *ff_rtp_handler_iterate(void **opaque)
>  {
> -    handler->next = rtp_first_dynamic_payload_handler;
> -    rtp_first_dynamic_payload_handler = handler;
> -}
> +    uintptr_t i = (uintptr_t)*opaque;
> +    const RTPDynamicProtocolHandler *r = rtp_dynamic_protocol_handler_list[i];
>
> -void ff_register_rtp_dynamic_payload_handlers(void)
> -{
> -    ff_register_dynamic_payload_handler(&ff_ac3_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_amr_nb_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_amr_wb_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_dv_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_g726_16_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_g726_24_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_g726_32_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_g726_40_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_g726le_16_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_g726le_24_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_g726le_32_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_g726le_40_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_h261_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_h263_1998_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_hevc_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_jpeg_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_mp4a_latm_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_mp4v_es_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_mpeg_audio_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_mpeg_audio_robust_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_mpeg_video_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_mpeg4_generic_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_mpegts_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler);
> -    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
> -    ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_qt_rtp_aud_handler);
> -    ff_register_dynamic_payload_handler(&ff_qt_rtp_vid_handler);
> -    ff_register_dynamic_payload_handler(&ff_quicktime_rtp_aud_handler);
> -    ff_register_dynamic_payload_handler(&ff_quicktime_rtp_vid_handler);
> -    ff_register_dynamic_payload_handler(&ff_rfc4175_rtp_handler);
> -    ff_register_dynamic_payload_handler(&ff_svq3_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_vc2hq_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_vp8_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&ff_vp9_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&gsm_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&l24_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&opus_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&speex_dynamic_handler);
> -    ff_register_dynamic_payload_handler(&t140_dynamic_handler);
> +    if (r)
> +        *opaque = (void*)(i + 1);
> +
> +    return r;
>  }
>
>  RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name,
>                                                         enum AVMediaType codec_type)
>  {
> -    RTPDynamicProtocolHandler *handler;
> -    for (handler = rtp_first_dynamic_payload_handler;
> -         handler; handler = handler->next)
> +    void *i = 0;
> +    const RTPDynamicProtocolHandler *handler;
> +    while (handler = ff_rtp_handler_iterate(&i)) {
>          if (handler->enc_name &&
>              !av_strcasecmp(name, handler->enc_name) &&
>              codec_type == handler->codec_type)
>              return handler;
> +    }
>      return NULL;
>  }
>
>  RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id,
>                                                       enum AVMediaType codec_type)
>  {
> -    RTPDynamicProtocolHandler *handler;
> -    for (handler = rtp_first_dynamic_payload_handler;
> -         handler; handler = handler->next)
> +    void *i = 0;
> +    const RTPDynamicProtocolHandler *handler;
> +    while (handler = ff_rtp_handler_iterate(&i)) {
>          if (handler->static_payload_id && handler->static_payload_id == id &&
>              codec_type == handler->codec_type)
>              return handler;
> +    }
>      return NULL;
>  }
>
> diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
> index 77596b6..fe726a6 100644
> --- a/libavformat/rtpdec.h
> +++ b/libavformat/rtpdec.h
> @@ -192,9 +192,30 @@ struct RTPDemuxContext {
>      PayloadContext *dynamic_protocol_context;
>  };
>
> -void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler);
> +/**
> + * Iterate over all registered rtp dynamic protocol handlers.
> + *
> + * @param opaque a pointer where libavformat will store the iteration state. Must
> + *               point to NULL to start the iteration.
> + *
> + * @return the next registered rtp dynamic protocol handler or NULL when the iteration is
> + *         finished
> + */
> +const RTPDynamicProtocolHandler *ff_rtp_handler_iterate(void **opaque);

Probably, this iterate function is not required, it is only used in rtpdec.c.

Patch hide | download patch | download mbox

diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index ec84096..83ed766 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -282,10 +282,6 @@  static void register_all(void)
     REGISTER_DEMUXER (SDR2,             sdr2);
     REGISTER_DEMUXER (SDS,              sds);
     REGISTER_DEMUXER (SDX,              sdx);
-#if CONFIG_RTPDEC
-    ff_register_rtp_dynamic_payload_handlers();
-    ff_register_rdt_dynamic_payload_handlers();
-#endif
     REGISTER_DEMUXER (SEGAFILM,         segafilm);
     REGISTER_MUXER   (SEGMENT,          segment);
     REGISTER_MUXER   (SEGMENT,          stream_segment);
diff --git a/libavformat/rdt.c b/libavformat/rdt.c
index b69827f..31a32ff 100644
--- a/libavformat/rdt.c
+++ b/libavformat/rdt.c
@@ -554,7 +554,7 @@  rdt_close_context (PayloadContext *rdt)
 }
 
 #define RDT_HANDLER(n, s, t) \
-static RTPDynamicProtocolHandler rdt_ ## n ## _handler = { \
+RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \
     .enc_name         = s, \
     .codec_type       = t, \
     .codec_id         = AV_CODEC_ID_NONE, \
@@ -570,10 +570,3 @@  RDT_HANDLER(live_audio, "x-pn-multirate-realaudio-live", AVMEDIA_TYPE_AUDIO);
 RDT_HANDLER(video,      "x-pn-realvideo",                AVMEDIA_TYPE_VIDEO);
 RDT_HANDLER(audio,      "x-pn-realaudio",                AVMEDIA_TYPE_AUDIO);
 
-void ff_register_rdt_dynamic_payload_handlers(void)
-{
-    ff_register_dynamic_payload_handler(&rdt_video_handler);
-    ff_register_dynamic_payload_handler(&rdt_audio_handler);
-    ff_register_dynamic_payload_handler(&rdt_live_video_handler);
-    ff_register_dynamic_payload_handler(&rdt_live_audio_handler);
-}
diff --git a/libavformat/rdt.h b/libavformat/rdt.h
index ce6026f..2480565 100644
--- a/libavformat/rdt.h
+++ b/libavformat/rdt.h
@@ -60,11 +60,6 @@  void ff_rdt_calc_response_and_checksum(char response[41], char chksum[9],
                                        const char *challenge);
 
 /**
- * Register RDT-related dynamic payload handlers with our cache.
- */
-void ff_register_rdt_dynamic_payload_handlers(void);
-
-/**
  * Add subscription information to Subscribe parameter string.
  *
  * @param cmd string to write the subscription information into.
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 4acb1ca..6499e27 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -69,88 +69,104 @@  static RTPDynamicProtocolHandler t140_dynamic_handler = { /* RFC 4103 */
     .codec_id   = AV_CODEC_ID_TEXT,
 };
 
-static RTPDynamicProtocolHandler *rtp_first_dynamic_payload_handler = NULL;
+extern RTPDynamicProtocolHandler ff_rdt_video_handler;
+extern RTPDynamicProtocolHandler ff_rdt_audio_handler;
+extern RTPDynamicProtocolHandler ff_rdt_live_video_handler;
+extern RTPDynamicProtocolHandler ff_rdt_live_audio_handler;
+
+static const RTPDynamicProtocolHandler *rtp_dynamic_protocol_handler_list[] = {
+    /* rtp */
+    &ff_ac3_dynamic_handler,
+    &ff_amr_nb_dynamic_handler,
+    &ff_amr_wb_dynamic_handler,
+    &ff_dv_dynamic_handler,
+    &ff_g726_16_dynamic_handler,
+    &ff_g726_24_dynamic_handler,
+    &ff_g726_32_dynamic_handler,
+    &ff_g726_40_dynamic_handler,
+    &ff_g726le_16_dynamic_handler,
+    &ff_g726le_24_dynamic_handler,
+    &ff_g726le_32_dynamic_handler,
+    &ff_g726le_40_dynamic_handler,
+    &ff_h261_dynamic_handler,
+    &ff_h263_1998_dynamic_handler,
+    &ff_h263_2000_dynamic_handler,
+    &ff_h263_rfc2190_dynamic_handler,
+    &ff_h264_dynamic_handler,
+    &ff_hevc_dynamic_handler,
+    &ff_ilbc_dynamic_handler,
+    &ff_jpeg_dynamic_handler,
+    &ff_mp4a_latm_dynamic_handler,
+    &ff_mp4v_es_dynamic_handler,
+    &ff_mpeg_audio_dynamic_handler,
+    &ff_mpeg_audio_robust_dynamic_handler,
+    &ff_mpeg_video_dynamic_handler,
+    &ff_mpeg4_generic_dynamic_handler,
+    &ff_mpegts_dynamic_handler,
+    &ff_ms_rtp_asf_pfa_handler,
+    &ff_ms_rtp_asf_pfv_handler,
+    &ff_qcelp_dynamic_handler,
+    &ff_qdm2_dynamic_handler,
+    &ff_qt_rtp_aud_handler,
+    &ff_qt_rtp_vid_handler,
+    &ff_quicktime_rtp_aud_handler,
+    &ff_quicktime_rtp_vid_handler,
+    &ff_rfc4175_rtp_handler,
+    &ff_svq3_dynamic_handler,
+    &ff_theora_dynamic_handler,
+    &ff_vc2hq_dynamic_handler,
+    &ff_vorbis_dynamic_handler,
+    &ff_vp8_dynamic_handler,
+    &ff_vp9_dynamic_handler,
+    &gsm_dynamic_handler,
+    &l24_dynamic_handler,
+    &opus_dynamic_handler,
+    &realmedia_mp3_dynamic_handler,
+    &speex_dynamic_handler,
+    &t140_dynamic_handler,
+    /* rdt */
+    &ff_rdt_video_handler,
+    &ff_rdt_audio_handler,
+    &ff_rdt_live_video_handler,
+    &ff_rdt_live_audio_handler,
+    NULL,
+};
 
-void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
+const RTPDynamicProtocolHandler *ff_rtp_handler_iterate(void **opaque)
 {
-    handler->next = rtp_first_dynamic_payload_handler;
-    rtp_first_dynamic_payload_handler = handler;
-}
+    uintptr_t i = (uintptr_t)*opaque;
+    const RTPDynamicProtocolHandler *r = rtp_dynamic_protocol_handler_list[i];
 
-void ff_register_rtp_dynamic_payload_handlers(void)
-{
-    ff_register_dynamic_payload_handler(&ff_ac3_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_amr_nb_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_amr_wb_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_dv_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_16_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_24_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_32_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_40_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726le_16_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726le_24_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726le_32_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726le_40_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_h261_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_h263_1998_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_hevc_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_jpeg_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_mp4a_latm_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_mp4v_es_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_mpeg_audio_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_mpeg_audio_robust_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_mpeg_video_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_mpeg4_generic_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_mpegts_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler);
-    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
-    ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_qt_rtp_aud_handler);
-    ff_register_dynamic_payload_handler(&ff_qt_rtp_vid_handler);
-    ff_register_dynamic_payload_handler(&ff_quicktime_rtp_aud_handler);
-    ff_register_dynamic_payload_handler(&ff_quicktime_rtp_vid_handler);
-    ff_register_dynamic_payload_handler(&ff_rfc4175_rtp_handler);
-    ff_register_dynamic_payload_handler(&ff_svq3_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_vc2hq_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_vp8_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_vp9_dynamic_handler);
-    ff_register_dynamic_payload_handler(&gsm_dynamic_handler);
-    ff_register_dynamic_payload_handler(&l24_dynamic_handler);
-    ff_register_dynamic_payload_handler(&opus_dynamic_handler);
-    ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
-    ff_register_dynamic_payload_handler(&speex_dynamic_handler);
-    ff_register_dynamic_payload_handler(&t140_dynamic_handler);
+    if (r)
+        *opaque = (void*)(i + 1);
+
+    return r;
 }
 
 RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name,
                                                        enum AVMediaType codec_type)
 {
-    RTPDynamicProtocolHandler *handler;
-    for (handler = rtp_first_dynamic_payload_handler;
-         handler; handler = handler->next)
+    void *i = 0;
+    const RTPDynamicProtocolHandler *handler;
+    while (handler = ff_rtp_handler_iterate(&i)) {
         if (handler->enc_name &&
             !av_strcasecmp(name, handler->enc_name) &&
             codec_type == handler->codec_type)
             return handler;
+    }
     return NULL;
 }
 
 RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id,
                                                      enum AVMediaType codec_type)
 {
-    RTPDynamicProtocolHandler *handler;
-    for (handler = rtp_first_dynamic_payload_handler;
-         handler; handler = handler->next)
+    void *i = 0;
+    const RTPDynamicProtocolHandler *handler;
+    while (handler = ff_rtp_handler_iterate(&i)) {
         if (handler->static_payload_id && handler->static_payload_id == id &&
             codec_type == handler->codec_type)
             return handler;
+    }
     return NULL;
 }
 
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 77596b6..fe726a6 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -192,9 +192,30 @@  struct RTPDemuxContext {
     PayloadContext *dynamic_protocol_context;
 };
 
-void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler);
+/**
+ * Iterate over all registered rtp dynamic protocol handlers.
+ *
+ * @param opaque a pointer where libavformat will store the iteration state. Must
+ *               point to NULL to start the iteration.
+ *
+ * @return the next registered rtp dynamic protocol handler or NULL when the iteration is
+ *         finished
+ */
+const RTPDynamicProtocolHandler *ff_rtp_handler_iterate(void **opaque);
+/**
+ * Find a registered rtp dynamic protocol handler with the specified name.
+ *
+ * @param name name of the requested rtp dynamic protocol handler
+ * @return A rtp dynamic protocol handler if one was found, NULL otherwise.
+ */
 RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name,
                                                   enum AVMediaType codec_type);
+/**
+ * Find a registered rtp dynamic protocol handler with a matching codec ID.
+ *
+ * @param id AVCodecID of the requested rtp dynamic protocol handler.
+ * @return A rtp dynamic protocol handler if one was found, NULL otherwise.
+ */
 RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id,
                                                 enum AVMediaType codec_type);
 
@@ -209,8 +230,6 @@  int ff_parse_fmtp(AVFormatContext *s,
                                     PayloadContext *data,
                                     const char *attr, const char *value));
 
-void ff_register_rtp_dynamic_payload_handlers(void);
-
 /**
  * Close the dynamic buffer and make a packet from it.
  */