[FFmpeg-devel] [PATCH 2/6] lavf/rtp: replace linked list with array
Josh de Kock
josh at itanimul.li
Wed Jan 3 02:42:45 EET 2018
---
libavformat/allformats.c | 4 --
libavformat/rdt.c | 8 +--
libavformat/rdt.h | 3 +
libavformat/rtpdec.c | 157 ++++++++++++++++++++++++++++++-----------------
libavformat/rtpdec.h | 29 ++++++++-
libavformat/version.h | 4 +-
6 files changed, 136 insertions(+), 69 deletions(-)
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 6a9b988..593baf3 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -283,10 +283,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..4d6321e 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,8 @@ 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);
+#if FF_API_RTP_NEXT
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);
}
+#endif
diff --git a/libavformat/rdt.h b/libavformat/rdt.h
index ce6026f..a87057d 100644
--- a/libavformat/rdt.h
+++ b/libavformat/rdt.h
@@ -59,10 +59,13 @@ void ff_rdt_parse_close(RDTDemuxContext *s);
void ff_rdt_calc_response_and_checksum(char response[41], char chksum[9],
const char *challenge);
+#if FF_API_RTP_NEXT
/**
* Register RDT-related dynamic payload handlers with our cache.
*/
+attribute_deprecated
void ff_register_rdt_dynamic_payload_handlers(void);
+#endif
/**
* Add subscription information to Subscribe parameter string.
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 4acb1ca..2e777c9 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -22,6 +22,7 @@
#include "libavutil/mathematics.h"
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/thread.h"
#include "libavutil/time.h"
#include "avformat.h"
@@ -69,88 +70,130 @@ 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,
+};
+
+const RTPDynamicProtocolHandler *ff_rtp_handler_iterate(void **opaque)
+{
+ uintptr_t i = (uintptr_t)*opaque;
+ const RTPDynamicProtocolHandler *r = rtp_dynamic_protocol_handler_list[i];
+
+ if (r)
+ *opaque = (void*)(i + 1);
+
+ return r;
+}
+
+#if FF_API_NEXT
+pthread_once_t ff_rtp_handler_next_init = PTHREAD_ONCE_INIT;
+
+static void ff_rtp_handler_init_next(void)
+{
+ AVCodec *prev = NULL, *p;
+ void *i = 0;
+ while ((p = (AVCodec*)av_codec_iterate(&i))) {
+ if (prev)
+ prev->next = p;
+ prev = p;
+ }
+ prev->next = NULL;
+}
void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
{
- handler->next = rtp_first_dynamic_payload_handler;
- rtp_first_dynamic_payload_handler = handler;
+ pthread_once(&ff_rtp_handler_next_init, ff_rtp_handler_init_next);
}
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);
+ pthread_once(&ff_rtp_handler_next_init, ff_rtp_handler_init_next);
}
+#endif
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..e59c99c 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -192,9 +192,36 @@ struct RTPDemuxContext {
PayloadContext *dynamic_protocol_context;
};
+#if FF_API_RTP_NEXT
+attribute_deprecated
void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler);
+attribute_deprecated
+void ff_register_rtp_dynamic_payload_handlers(void);
+#endif
+/**
+ * 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 +236,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.
*/
diff --git a/libavformat/version.h b/libavformat/version.h
index 5ced041..3b2a188 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -82,7 +82,9 @@
#ifndef FF_API_OLD_AVIO_EOF_0
#define FF_API_OLD_AVIO_EOF_0 (LIBAVFORMAT_VERSION_MAJOR < 59)
#endif
-
+#ifndef FF_API_RTP_NEXT
+#define FF_API_RTP_NEXT (LIBAVFORMAT_VERSION_MAJOR < 59)
+#endif
#ifndef FF_API_R_FRAME_RATE
#define FF_API_R_FRAME_RATE 1
--
2.7.4
More information about the ffmpeg-devel
mailing list