[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