[vlc-commits] [Git][videolan/vlc][master] 7 commits: rtp: fix assigned dynamic payload types

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Fri Nov 19 20:21:39 UTC 2021



Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC


Commits:
ca57d660 by Rémi Denis-Courmont at 2021-11-19T21:48:02+02:00
rtp: fix assigned dynamic payload types

- - - - -
422142d3 by Rémi Denis-Courmont at 2021-11-19T21:48:03+02:00
rtp: fix typo

- - - - -
cdf3b2f1 by Rémi Denis-Courmont at 2021-11-19T21:48:03+02:00
rtp: add owner structure to payload types

- - - - -
52f2e336 by Rémi Denis-Courmont at 2021-11-19T21:48:03+02:00
rtp: remove unused Xiph parser (again)

- - - - -
5046b7a4 by Rémi Denis-Courmont at 2021-11-19T21:48:03+02:00
rtp: remove unused demux parameter

- - - - -
504d5aa6 by Rémi Denis-Courmont at 2021-11-19T21:48:03+02:00
rtp: add PT owner callbacks

- - - - -
cafec9d0 by Rémi Denis-Courmont at 2021-11-19T21:48:03+02:00
rtp: add module capabilities for RTP payload type parsers

- - - - -


6 changed files:

- modules/access/rtp/Makefile.am
- modules/access/rtp/rtp.c
- modules/access/rtp/rtp.h
- modules/access/rtp/rtpfmt.c
- modules/access/rtp/session.c
- modules/access/rtp/xiph.c


Changes:

=====================================
modules/access/rtp/Makefile.am
=====================================
@@ -3,7 +3,6 @@ access_LTLIBRARIES += librtp_plugin.la
 librtp_plugin_la_SOURCES = \
 	access/rtp/input.c \
 	access/rtp/session.c \
-	access/rtp/xiph.c \
 	access/rtp/sdp.c access/rtp/sdp.h \
 	access/rtp/rtpfmt.c \
 	access/rtp/datagram.c access/rtp/vlc_dtls.h \


=====================================
modules/access/rtp/rtp.c
=====================================
@@ -85,10 +85,10 @@ static const struct vlc_rtp_es_operations vlc_rtp_es_id_ops = {
     vlc_rtp_es_id_destroy, vlc_rtp_es_id_send,
 };
 
-struct vlc_rtp_es *vlc_rtp_es_request(void *data,
-                                      const es_format_t *restrict fmt)
+static struct vlc_rtp_es *vlc_rtp_es_request(struct vlc_rtp_pt *pt,
+                                             const es_format_t *restrict fmt)
 {
-    demux_t *demux = data;
+    demux_t *demux = pt->owner.data;
 
     struct vlc_rtp_es_id *ei = malloc(sizeof (*ei));
     if (unlikely(ei == NULL))
@@ -128,9 +128,10 @@ static const struct vlc_rtp_es_operations vlc_rtp_es_mux_ops = {
     vlc_rtp_es_mux_destroy, vlc_rtp_es_mux_send,
 };
 
-struct vlc_rtp_es *vlc_rtp_mux_request(void *data, const char *name)
+static struct vlc_rtp_es *vlc_rtp_mux_request(struct vlc_rtp_pt *pt,
+                                              const char *name)
 {
-    demux_t *demux = data;
+    demux_t *demux = pt->owner.data;
 
     struct vlc_rtp_es_mux *em = malloc(sizeof (*em));
     if (unlikely(em == NULL))
@@ -146,6 +147,44 @@ struct vlc_rtp_es *vlc_rtp_mux_request(void *data, const char *name)
     return &em->es;
 }
 
+static const struct vlc_rtp_pt_owner_operations vlc_rtp_pt_owner_ops = {
+    vlc_rtp_es_request, vlc_rtp_mux_request,
+};
+
+int vlc_rtp_pt_instantiate(vlc_object_t *obj, struct vlc_rtp_pt *restrict pt,
+                           const struct vlc_sdp_pt *restrict desc)
+{
+    char modname[32];
+    int ret = VLC_ENOTSUP;
+
+    if (strchr(desc->name, ',') != NULL)
+        /* Comma has special meaning in vlc_module_match(), forbid it */
+        return VLC_EINVAL;
+    if ((size_t)snprintf(modname, sizeof (modname), "%s/%s",
+                         desc->media->type, desc->name) >= sizeof (modname))
+        return VLC_ENOTSUP; /* Outlandish media type with long name */
+
+    module_t **mods;
+    ssize_t n = vlc_module_match("rtp parser", modname, true, &mods, NULL);
+
+    for (ssize_t i = 0; i < n; i++) {
+        vlc_rtp_parser_cb cb = vlc_module_map(vlc_object_logger(obj), mods[i]);
+        if (cb == NULL)
+            continue;
+
+        ret = cb(obj, pt, desc);
+        if (ret == VLC_SUCCESS) {
+            msg_Dbg(obj, "- module \"%s\"", module_get_name(mods[i], true));
+            assert(pt->ops != NULL);
+            ret = 0;
+            break;
+        }
+    }
+
+    free(mods);
+    return ret;
+}
+
 /**
  * Extracts port number from "[host]:port" or "host:port" strings,
  * and remove brackets from the host name.
@@ -391,7 +430,8 @@ static int OpenSDP(vlc_object_t *obj)
         goto error;
 
     /* Parse payload types */
-    int err = vlc_rtp_add_media_types(obj, sys->session, media);
+    const struct vlc_rtp_pt_owner pt_owner = { &vlc_rtp_pt_owner_ops, demux };
+    int err = vlc_rtp_add_media_types(obj, sys->session, media, &pt_owner);
     if (err < 0) {
         msg_Err(obj, "SDP description parse error");
         goto error;
@@ -541,7 +581,8 @@ static int OpenURL(vlc_object_t *obj)
     if (p_sys->session == NULL)
         goto error;
 
-    rtp_autodetect(VLC_OBJECT(demux), p_sys->session);
+    const struct vlc_rtp_pt_owner pt_owner = { &vlc_rtp_pt_owner_ops, demux };
+    rtp_autodetect(VLC_OBJECT(demux), p_sys->session, &pt_owner);
 
 #ifdef HAVE_SRTP
     char *key = var_CreateGetNonEmptyString (demux, "srtp-key");


=====================================
modules/access/rtp/rtp.h
=====================================
@@ -83,7 +83,7 @@ struct vlc_rtp_pt_operations {
      * \param pt RTP payload format being taken into use
      * \return a data pointer for decode() and destroy() callbacks
      */
-    void *(*init)(struct vlc_rtp_pt *pt, demux_t *);
+    void *(*init)(struct vlc_rtp_pt *pt);
 
     /**
      * Stops using a payload format.
@@ -105,6 +105,20 @@ struct vlc_rtp_pt_operations {
     void (*decode)(struct vlc_rtp_pt *pt, void *data, block_t *block);
 };
 
+struct vlc_rtp_pt_owner;
+struct vlc_rtp_es;
+
+struct vlc_rtp_pt_owner_operations {
+    struct vlc_rtp_es *(*request_es)(struct vlc_rtp_pt *pt,
+                                     const es_format_t *restrict fmt);
+    struct vlc_rtp_es *(*request_mux)(struct vlc_rtp_pt *pt, const char *name);
+};
+
+struct vlc_rtp_pt_owner {
+    const struct vlc_rtp_pt_owner_operations *ops;
+    void *data;
+};
+
 /**
  * RTP payload format.
  *
@@ -115,6 +129,7 @@ struct vlc_rtp_pt
 {
     const struct vlc_rtp_pt_operations *ops; /**< Payload format callbacks */
     void *opaque; /**< Private data pointer */
+    struct vlc_rtp_pt_owner owner;
     uint32_t frequency; /**< RTP clock rate (Hz) */
     uint8_t number; /**< RTP payload type number within the session (0-127) */
     uint8_t channel_count; /**< Channel count (zero if unspecified) */
@@ -134,13 +149,12 @@ void vlc_rtp_pt_release(struct vlc_rtp_pt *pt);
  * type for use by an unique RTP source.
  *
  * @param pt RTP payload type to instantiate
- * @param demux demux object for output
  * @return private data for the instance
  */
-static inline void *vlc_rtp_pt_begin(struct vlc_rtp_pt *pt, demux_t *demux)
+static inline void *vlc_rtp_pt_begin(struct vlc_rtp_pt *pt)
 {
     assert(pt->ops->init != NULL);
-    return pt->ops->init(pt, demux);
+    return pt->ops->init(pt);
 }
 
 /**
@@ -170,7 +184,19 @@ static inline void vlc_rtp_pt_decode(struct vlc_rtp_pt *pt,
     pt->ops->decode(pt, data, pkt);
 }
 
-struct vlc_rtp_es;
+static inline
+struct vlc_rtp_es *vlc_rtp_pt_request_es(struct vlc_rtp_pt *pt,
+                                         const es_format_t *restrict fmt)
+{
+    return pt->owner.ops->request_es(pt, fmt);
+}
+
+static inline
+struct vlc_rtp_es *vlc_rtp_pt_request_mux(struct vlc_rtp_pt *pt,
+                                          const char *name)
+{
+    return pt->owner.ops->request_mux(pt, name);
+}
 
 /**
  * RTP elementary output stream operations.
@@ -218,19 +244,38 @@ static inline void vlc_rtp_es_send(struct vlc_rtp_es *es, block_t *block)
  */
 extern struct vlc_rtp_es *const vlc_rtp_es_dummy;
 
-struct vlc_rtp_es *vlc_rtp_es_request(void *, const es_format_t *fmt);
-struct vlc_rtp_es *vlc_rtp_mux_request(void *, const char *name);
+/**
+ * Callback prototype for RTP parser module.
+ *
+ * This is the callback prototype for any RTP payload format parser module.
+ *
+ * \param obj VLC object for logging and configuration
+ * \param pt RTP payload type
+ * \param desc[in] SDP payload format description and type mapping
+ *
+ * \return VLC_SUCCESS on success, an error code on failure.
+ */
+typedef int (*vlc_rtp_parser_cb)(vlc_object_t *obj, struct vlc_rtp_pt *pt,
+                                 const struct vlc_sdp_pt *desc);
 
+#define set_rtp_parser_callback(cb) \
+    { \
+        vlc_rtp_parser_cb cb__ = (cb); (void) cb__; \
+        set_callback(cb); \
+        set_capability("rtp parser", 0); \
+    }
 
-void rtp_autodetect(vlc_object_t *, rtp_session_t *);
+int vlc_rtp_pt_instantiate(vlc_object_t *obj, struct vlc_rtp_pt *restrict pt,
+                           const struct vlc_sdp_pt *restrict desc);
+
+void rtp_autodetect(vlc_object_t *, rtp_session_t *,
+                    const struct vlc_rtp_pt_owner *restrict);
 
 static inline uint8_t rtp_ptype (const block_t *block)
 {
     return block->p_buffer[1] & 0x7F;
 }
 
-extern const struct vlc_rtp_pt_operations rtp_video_theora;
-
 /** @} */
 
 /**
@@ -243,7 +288,8 @@ void rtp_queue (demux_t *, rtp_session_t *, block_t *);
 bool rtp_dequeue (demux_t *, const rtp_session_t *, vlc_tick_t *);
 int rtp_add_type(rtp_session_t *ses, rtp_pt_t *pt);
 int vlc_rtp_add_media_types(vlc_object_t *obj, rtp_session_t *ses,
-                            const struct vlc_sdp_media *media);
+                            const struct vlc_sdp_media *media,
+                            const struct vlc_rtp_pt_owner *restrict owner);
 
 void *rtp_dgram_thread (void *data);
 


=====================================
modules/access/rtp/rtpfmt.c
=====================================
@@ -28,7 +28,6 @@
 #include <errno.h>
 
 #include <vlc_common.h>
-#include <vlc_demux.h>
 #include <vlc_aout.h> /* aout_FormatPrepare() */
 
 #include "rtp.h"
@@ -59,14 +58,14 @@ static void codec_decode(struct vlc_rtp_pt *pt, void *data, block_t *block)
 /* PT=0
  * PCMU: G.711 µ-law (RFC3551)
  */
-static void *pcmu_init(struct vlc_rtp_pt *pt, demux_t *demux)
+static void *pcmu_init(struct vlc_rtp_pt *pt)
 {
     es_format_t fmt;
 
     es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_MULAW);
     fmt.audio.i_rate = pt->frequency;
     fmt.audio.i_channels = pt->channel_count ? pt->channel_count : 1;
-    return vlc_rtp_es_request(demux, &fmt);
+    return vlc_rtp_pt_request_es(pt, &fmt);
 }
 
 static const struct vlc_rtp_pt_operations rtp_audio_pcmu = {
@@ -76,15 +75,14 @@ static const struct vlc_rtp_pt_operations rtp_audio_pcmu = {
 /* PT=3
  * GSM
  */
-static void *gsm_init(struct vlc_rtp_pt *pt, demux_t *demux)
+static void *gsm_init(struct vlc_rtp_pt *pt)
 {
     es_format_t fmt;
 
     es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_GSM);
     fmt.audio.i_rate = 8000;
     fmt.audio.i_physical_channels = AOUT_CHAN_CENTER;
-    (void) pt;
-    return vlc_rtp_es_request(demux, &fmt);
+    return vlc_rtp_pt_request_es(pt, &fmt);
 }
 
 static const struct vlc_rtp_pt_operations rtp_audio_gsm = {
@@ -94,14 +92,14 @@ static const struct vlc_rtp_pt_operations rtp_audio_gsm = {
 /* PT=8
  * PCMA: G.711 A-law (RFC3551)
  */
-static void *pcma_init(struct vlc_rtp_pt *pt, demux_t *demux)
+static void *pcma_init(struct vlc_rtp_pt *pt)
 {
     es_format_t fmt;
 
     es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_ALAW);
     fmt.audio.i_rate = pt->frequency;
     fmt.audio.i_channels = pt->channel_count ? pt->channel_count : 1;
-    return vlc_rtp_es_request(demux, &fmt);
+    return vlc_rtp_pt_request_es(pt, &fmt);
 }
 
 static const struct vlc_rtp_pt_operations rtp_audio_pcma = {
@@ -111,14 +109,14 @@ static const struct vlc_rtp_pt_operations rtp_audio_pcma = {
 /* PT=10,11
  * L16: 16-bits (network byte order) PCM
  */
-static void *l16_init(struct vlc_rtp_pt *pt, demux_t *demux)
+static void *l16_init(struct vlc_rtp_pt *pt)
 {
     es_format_t fmt;
 
     es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_S16B);
     fmt.audio.i_rate = pt->frequency;
     fmt.audio.i_channels = pt->channel_count ? pt->channel_count : 1;
-    return vlc_rtp_es_request(demux, &fmt);
+    return vlc_rtp_pt_request_es(pt, &fmt);
 }
 
 static const struct vlc_rtp_pt_operations rtp_audio_l16 = {
@@ -128,15 +126,14 @@ static const struct vlc_rtp_pt_operations rtp_audio_l16 = {
 /* PT=12
  * QCELP
  */
-static void *qcelp_init(struct vlc_rtp_pt *pt, demux_t *demux)
+static void *qcelp_init(struct vlc_rtp_pt *pt)
 {
     es_format_t fmt;
 
     es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_QCELP);
     fmt.audio.i_rate = 8000;
     fmt.audio.i_physical_channels = AOUT_CHAN_CENTER;
-    (void) pt;
-    return vlc_rtp_es_request(demux, &fmt);
+    return vlc_rtp_pt_request_es(pt, &fmt);
 }
 
 static const struct vlc_rtp_pt_operations rtp_audio_qcelp = {
@@ -146,14 +143,13 @@ static const struct vlc_rtp_pt_operations rtp_audio_qcelp = {
 /* PT=14
  * MPA: MPEG Audio (RFC2250, §3.4)
  */
-static void *mpa_init(struct vlc_rtp_pt *pt, demux_t *demux)
+static void *mpa_init(struct vlc_rtp_pt *pt)
 {
     es_format_t fmt;
 
     es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_MPGA);
     fmt.b_packetized = false;
-    (void) pt;
-    return vlc_rtp_es_request(demux, &fmt);
+    return vlc_rtp_pt_request_es(pt, &fmt);
 }
 
 static void mpa_decode(struct vlc_rtp_pt *pt, void *data, block_t *block)
@@ -178,14 +174,13 @@ static const struct vlc_rtp_pt_operations rtp_audio_mpa = {
 /* PT=32
  * MPV: MPEG Video (RFC2250, §3.5)
  */
-static void *mpv_init(struct vlc_rtp_pt *pt, demux_t *demux)
+static void *mpv_init(struct vlc_rtp_pt *pt)
 {
     es_format_t fmt;
 
     es_format_Init (&fmt, VIDEO_ES, VLC_CODEC_MPGV);
     fmt.b_packetized = false;
-    (void) pt;
-    return vlc_rtp_es_request(demux, &fmt);
+    return vlc_rtp_pt_request_es(pt, &fmt);
 }
 
 static void mpv_decode(struct vlc_rtp_pt *pt, void *data, block_t *block)
@@ -217,10 +212,9 @@ static const struct vlc_rtp_pt_operations rtp_video_mpv = {
 /* PT=33
  * MP2: MPEG TS (RFC2250, §2)
  */
-static void *ts_init(struct vlc_rtp_pt *pt, demux_t *demux)
+static void *ts_init(struct vlc_rtp_pt *pt)
 {
-    (void) pt;
-    return vlc_rtp_mux_request(demux, "ts");
+    return vlc_rtp_pt_request_mux(pt, "ts");
 }
 
 static const struct vlc_rtp_pt_operations rtp_av_ts = {
@@ -229,17 +223,18 @@ static const struct vlc_rtp_pt_operations rtp_av_ts = {
 
 /* Not using SDP, we need to guess the payload format used */
 /* see http://www.iana.org/assignments/rtp-parameters */
-void rtp_autodetect(vlc_object_t *obj, rtp_session_t *session)
+void rtp_autodetect(vlc_object_t *obj, rtp_session_t *session,
+                    const struct vlc_rtp_pt_owner *restrict owner)
 {
     char type[] = "audio", proto[] = "RTP/AVP";
     char format[] = "0 3 8 10 11 12 14 33";
     struct vlc_sdp_media media = {
         .type = type, .port_count = 1, .proto = proto, .format = format };
 
-    vlc_rtp_add_media_types(obj, session, &media);
+    vlc_rtp_add_media_types(obj, session, &media, owner);
     strcpy(type, "video");
     strcpy(format, "32");
-    vlc_rtp_add_media_types(obj, session, &media);
+    vlc_rtp_add_media_types(obj, session, &media, owner);
 }
 
 /*
@@ -247,7 +242,8 @@ void rtp_autodetect(vlc_object_t *obj, rtp_session_t *session)
  */
 
 static struct vlc_rtp_pt *vlc_rtp_pt_create(vlc_object_t *obj,
-                                            const struct vlc_sdp_pt *desc)
+                                            const struct vlc_sdp_pt *desc,
+                                 const struct vlc_rtp_pt_owner *restrict owner)
 {
     if (desc->clock_rate == 0) {
         /* Dynamic payload type not defined in the SDP */
@@ -259,11 +255,15 @@ static struct vlc_rtp_pt *vlc_rtp_pt_create(vlc_object_t *obj,
     if (unlikely(pt == NULL))
         return NULL;
 
+    pt->owner = *owner;
     pt->frequency = desc->clock_rate;
     pt->channel_count = desc->channel_count;
+
+    if (vlc_rtp_pt_instantiate(obj, pt, desc) == 0)
+        return pt;
+
     pt->ops = NULL;
 
-    /* TODO: introduce module (capabilities) for payload types */
     if (strcmp(desc->media->type, "audio") == 0) {
         if (strcmp(desc->name, "PCMU") == 0)
             pt->ops = &rtp_audio_pcmu;
@@ -273,7 +273,7 @@ static struct vlc_rtp_pt *vlc_rtp_pt_create(vlc_object_t *obj,
             pt->ops = &rtp_audio_pcma;
         else if (strcmp(desc->name, "L16") == 0)
             pt->ops = &rtp_audio_l16;
-        else if (strcmp(desc->name, "QCLEP") == 0)
+        else if (strcmp(desc->name, "QCELP") == 0)
             pt->ops = &rtp_audio_qcelp;
         else if (strcmp(desc->name, "MPA") == 0)
             pt->ops = &rtp_audio_mpa;
@@ -372,7 +372,8 @@ static void vlc_rtp_set_default_types(struct vlc_sdp_pt *restrict types,
  * Registers all payload types declared in an SDP media.
  */
 int vlc_rtp_add_media_types(vlc_object_t *obj, rtp_session_t *session,
-                            const struct vlc_sdp_media *media)
+                            const struct vlc_sdp_media *media,
+                            const struct vlc_rtp_pt_owner *restrict owner)
 {
     struct vlc_sdp_pt types[128] = { };
 
@@ -392,6 +393,7 @@ int vlc_rtp_add_media_types(vlc_object_t *obj, rtp_session_t *session,
                     /* fall through */
                 case 4:
                     if (number < ARRAY_SIZE(types)) {
+                        types[number].media = media;
                         strcpy(types[number].name, name);
                         types[number].clock_rate = frequency;
                         types[number].channel_count = channels;
@@ -439,7 +441,7 @@ int vlc_rtp_add_media_types(vlc_object_t *obj, rtp_session_t *session,
         if (type->parameters != NULL)
             msg_Dbg(obj, " - parameters: %s", type->parameters);
 
-        struct vlc_rtp_pt *pt = vlc_rtp_pt_create(obj, type);
+        struct vlc_rtp_pt *pt = vlc_rtp_pt_create(obj, type, owner);
         if (pt != NULL) {
             pt->number = number;
             if (rtp_add_type(session, pt))


=====================================
modules/access/rtp/session.c
=====================================
@@ -472,7 +472,7 @@ rtp_decode (demux_t *demux, const rtp_session_t *session, rtp_source_t *src)
             vlc_rtp_pt_end(src->pt.instance, src->pt.opaque);
 
         src->pt.instance = pt;
-        src->pt.opaque = vlc_rtp_pt_begin(pt, demux);
+        src->pt.opaque = vlc_rtp_pt_begin(pt);
     }
 
     /* Computes the PTS from the RTP timestamp and payload RTP frequency..


=====================================
modules/access/rtp/xiph.c
=====================================
@@ -71,7 +71,7 @@ static void *vorbis_init (demux_t *demux)
 /* PT=dynamic
  * vorbis: Xiph Theora video
  */
-static void *theora_init(struct vlc_rtp_pt *pt, demux_t *demux)
+static void *theora_init(struct vlc_rtp_pt *pt)
 {
     pt->opaque = demux;
     return xiph_init (false);
@@ -275,7 +275,7 @@ static void xiph_decode(struct vlc_rtp_pt *pt, void *data, block_t *block)
                          "Theora packed configuration received (%06"PRIx32")",
                          ident);
                 self->ident = ident;
-                self->id = vlc_rtp_es_request(demux, &fmt);
+                self->id = vlc_rtp_pt_request_es(pt, &fmt);
                 break;
             }
         }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/340d90556cf0d05aedc2fda6e8abf6d0dd300534...cafec9d0cec021f05c31930016057235efb4550f

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/340d90556cf0d05aedc2fda6e8abf6d0dd300534...cafec9d0cec021f05c31930016057235efb4550f
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list