From: Rémi Denis-Courmont Date: Tue, 3 Jun 2008 20:32:27 +0000 (+0300) Subject: RTP: add support for MPA and MPV static payload formats X-Git-Tag: 0.9.0-test0~397 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=91f7b6f52527c671ddafcb0f478a33a83ce0f379;p=vlc RTP: add support for MPA and MPV static payload formats --- diff --git a/modules/demux/rtp.c b/modules/demux/rtp.c index 2695cfeb56..9f070c8ba8 100644 --- a/modules/demux/rtp.c +++ b/modules/demux/rtp.c @@ -145,7 +145,7 @@ static int Open (vlc_object_t *obj) if (p_sys == NULL) goto error; - var_Create (obj, "rtp-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); + p_sys->caching = var_CreateGetInteger (obj, "rtp-caching"); p_sys->max_src = var_CreateGetInteger (obj, "rtp-max-src"); p_sys->timeout = var_CreateGetInteger (obj, "rtp-timeout"); p_sys->max_dropout = var_CreateGetInteger (obj, "rtp-max-dropout"); @@ -166,7 +166,7 @@ static int Open (vlc_object_t *obj) error: net_Close (fd); free (p_sys); - return VLC_SUCCESS; + return VLC_EGENERIC; } @@ -217,8 +217,7 @@ static int extract_port (char **phost) */ static int Control (demux_t *demux, int i_query, va_list args) { - /*demux_sys_t *p_sys = demux->p_sys;*/ - (void)demux; + demux_sys_t *p_sys = demux->p_sys; switch (i_query) { @@ -240,7 +239,7 @@ static int Control (demux_t *demux, int i_query, va_list args) case DEMUX_GET_PTS_DELAY: { int64_t *v = va_arg (args, int64_t *); - *v = var_GetInteger (demux, "rtp-caching"); + *v = p_sys->caching; return 0; } } @@ -270,6 +269,33 @@ static block_t *rtp_dgram_recv (demux_t *demux, int fd) /* * Generic packet handlers */ + +static void *codec_init (demux_t *demux, es_format_t *fmt) +{ + return es_out_Add (demux->out, fmt); +} + +static void codec_destroy (demux_t *demux, void *data) +{ + if (data) + es_out_Del (demux->out, (es_out_id_t *)data); +} + +/* Send a packet to decoder */ +static void codec_decode (demux_t *demux, void *data, block_t *block) +{ + if (data) + { + block->i_dts = 0; /* RTP does not specify this */ + es_out_Control (demux->out, ES_OUT_SET_PCR, + block->i_pts - demux->p_sys->caching * 1000); + es_out_Send (demux->out, (es_out_id_t *)data, block); + } + else + block_Release (block); +} + + static void *stream_init (demux_t *demux, const char *name) { return stream_DemuxNew (demux, name, demux->out); @@ -287,9 +313,74 @@ static void stream_decode (demux_t *demux, void *data, block_t *block) { if (data) stream_DemuxSend ((stream_t *)data, block); + else + block_Release (block); (void)demux; } +/* + * Static payload types handler + */ + +/* PT=14 + * MPA: MPEG Audio (RFC2250, §3.4) + */ +static void *mpa_init (demux_t *demux) +{ + es_format_t fmt; + + es_format_Init (&fmt, AUDIO_ES, VLC_FOURCC ('m', 'p', 'g', 'a')); + fmt.audio.i_channels = 2; + return codec_init (demux, &fmt); +} + +static void mpa_decode (demux_t *demux, void *data, block_t *block) +{ + if (block->i_buffer < 4) + { + block_Release (block); + return; + } + + block->i_buffer -= 4; /* 32-bits RTP/MPA header */ + block->p_buffer += 4; + + codec_decode (demux, data, block); +} + + +/* PT=32 + * MPV: MPEG Video (RFC2250, §3.5) + */ +static void *mpv_init (demux_t *demux) +{ + es_format_t fmt; + + es_format_Init (&fmt, VIDEO_ES, VLC_FOURCC ('m', 'p', 'g', 'v')); + return codec_init (demux, &fmt); +} + +static void mpv_decode (demux_t *demux, void *data, block_t *block) +{ + if (block->i_buffer < 4) + { + block_Release (block); + return; + } + + block->i_buffer -= 4; /* 32-bits RTP/MPV header */ + block->p_buffer += 4; +#if 0 + if (block->p_buffer[-3] & 0x4) + { + /* MPEG2 Video extension header */ + /* TODO: shouldn't we skip this too ? */ + } +#endif + codec_decode (demux, data, block); +} + + /* PT=33 * MP2: MPEG TS (RFC2250, §2) */ @@ -299,6 +390,11 @@ static void *ts_init (demux_t *demux) } +/* + * Dynamic payload type handlers + * Hmm, none implemented yet. + */ + /** * Processing callback */ @@ -313,17 +409,27 @@ static int Demux (demux_t *demux) /* Not using SDP, we need to guess the payload format used */ if (p_sys->autodetect && block->i_buffer >= 2) { - rtp_pt_t pt = { .init = NULL, }; - - switch (pt.number = (block->p_buffer[1] & 0x7f)) + rtp_pt_t pt = { + .init = NULL, + .destroy = codec_destroy, + .decode = codec_decode, + .frequency = 0, + .number = block->p_buffer[1] & 0x7f, + }; + + switch (pt.number) { case 14: msg_Dbg (demux, "detected MPEG Audio over RTP"); + pt.init = mpa_init; + pt.decode = mpa_decode; pt.frequency = 44100; break; case 32: msg_Dbg (demux, "detected MPEG Video over RTP"); + pt.init = mpv_init; + pt.decode = mpv_decode; pt.frequency = 90000; break; @@ -344,64 +450,3 @@ static int Demux (demux_t *demux) return 1; } - - -/* Send a packet to decoder */ -#if 0 -static void pt_decode (demux_t *obj, block_t *block, rtp_pt_t *self) -{ - p_block->i_pts = p_block->i_dts = date_... (...); - es_out_Control (obj->out, ES_OUT_SET_PCR, p_block->i_pts); - es_out_Send (obj->out, (es_out_id_t *)*p_id, block); - return 0; -} -#endif - - -#if 0 -/* - * Static payload types handler - */ - -/* PT=14 - * MPA: MPEG Audio (RFC2250, §3.4) - */ -static int pt_mpa (demux_t *obj, block_t *block, rtp_pt_t *self) -{ - if (block->i_buffer < 4) - return VLC_EGENERIC; - - block->i_buffer -= 4; // 32 bits RTP/MPA header - block->p_buffer += 4; - - return pt_demux (obj, block, self, "mpga"); -} - - -/* PT=32 - * MPV: MPEG Video (RFC2250, §3.5) - */ -static int pt_mpv (demux_t *obj, block_t *block, rtp_pt_t *self) -{ - if (block->i_buffer < 4) - return VLC_EGENERIC; - - block->i_buffer -= 4; // 32 bits RTP/MPV header - block->p_buffer += 4; - - if (block->p_buffer[-3] & 0x4) - { - /* MPEG2 Video extension header */ - /* TODO: shouldn't we skip this too ? */ - } - - return pt_demux (obj, block, self, "mpgv"); -} - - -#endif - -/* - * Dynamic payload type handlers - * Hmm, none implemented yet. - */ diff --git a/modules/demux/rtp.h b/modules/demux/rtp.h index 6b94d91671..04e6869ffb 100644 --- a/modules/demux/rtp.h +++ b/modules/demux/rtp.h @@ -45,6 +45,7 @@ struct demux_sys_t rtp_session_t *session; int fd; + unsigned caching; unsigned timeout; uint8_t max_src; uint16_t max_dropout; diff --git a/modules/demux/rtpsession.c b/modules/demux/rtpsession.c index 65ae1daccb..77266c946c 100644 --- a/modules/demux/rtpsession.c +++ b/modules/demux/rtpsession.c @@ -87,7 +87,8 @@ void rtp_session_destroy (demux_t *demux, rtp_session_t *session) static void *no_init (demux_t *demux) { - return demux; + (void)demux; + return NULL; } static void no_destroy (demux_t *demux, void *opaque) @@ -124,6 +125,8 @@ int rtp_add_type (demux_t *demux, rtp_session_t *ses, const rtp_pt_t *pt) ppt->decode = pt->decode ? pt->decode : no_decode; ppt->frequency = pt->frequency; ppt->number = pt->number; + msg_Dbg (demux, "added payload type %"PRIu8" (f = %"PRIu32" Hz)", + ppt->number, ppt->frequency); assert (ppt->frequency > 0); /* SIGFPE! */ (void)demux; @@ -139,7 +142,7 @@ struct rtp_source_t uint16_t max_seq; /* next expected sequence */ block_t *blocks; /* re-ordered blocks queue */ - void *opaque[0]; /* Per-source prviate payload data */ + void *opaque[0]; /* Per-source private payload data */ }; /** @@ -347,7 +350,6 @@ rtp_decode (demux_t *demux, const rtp_session_t *session, rtp_source_t *src) /* TODO: sync multiple sources sanely... */ const uint32_t timestamp = GetDWBE (block->p_buffer + 4); block->i_pts = UINT64_C(1) * CLOCK_FREQ * timestamp / pt->frequency; - //msg_Dbg (demux, "pts = %"PRIu64, block->i_pts); /* CSRC count */ size_t skip = 12u + (block->p_buffer[0] & 0x0F) * 4;