/** * Processes a packet received from the RTP socket. */ static void rtp_process (demux_t *demux, block_t *block) { demux_sys_t *sys = demux->p_sys; if (block->i_buffer < 2) goto drop; const uint8_t ptype = rtp_ptype (block); if (ptype >= 72 && ptype <= 76) goto drop; /* Muxed RTCP, ignore for now FIXME */ #ifdef HAVE_SRTP if (sys->srtp != NULL) { size_t len = block->i_buffer; if (srtp_recv (sys->srtp, block->p_buffer, &len)) { msg_Dbg (demux, "SRTP authentication/decryption failed"); goto drop; } block->i_buffer = len; } #endif /* TODO: use SDP and get rid of this hack */ if (unlikely(sys->autodetect)) { /* Autodetect payload type, _before_ rtp_queue() */ rtp_autodetect (demux, sys->session, block); sys->autodetect = false; } rtp_queue (demux, sys->session, block); return; drop: block_Release (block); }
static block_t *rtp_recv (demux_t *demux) { demux_sys_t *p_sys = demux->p_sys; for (block_t *block;; block_Release (block)) { block = p_sys->framed_rtp ? rtp_stream_recv (VLC_OBJECT (demux), p_sys->fd) : rtp_dgram_recv (VLC_OBJECT (demux), p_sys->fd); if (block == NULL) { msg_Err (demux, "RTP flow stopped"); break; /* fatal error */ } if (block->i_buffer < 2) continue; /* FIXME */ const uint8_t ptype = rtp_ptype (block); if (ptype >= 72 && ptype <= 76) continue; /* Muxed RTCP, ignore for now */ #ifdef HAVE_SRTP if (p_sys->srtp) { size_t len = block->i_buffer; int canc, err; canc = vlc_savecancel (); err = srtp_recv (p_sys->srtp, block->p_buffer, &len); vlc_restorecancel (canc); if (err) { msg_Dbg (demux, "SRTP authentication/decryption failed"); continue; } block->i_buffer = len; } #endif return block; /* success! */ } return NULL; }
/* see http://www.iana.org/assignments/rtp-parameters */ void rtp_autodetect (demux_t *demux, rtp_session_t *session, const block_t *block) { uint8_t ptype = rtp_ptype (block); rtp_pt_t pt = { .init = NULL, .destroy = codec_destroy, .decode = codec_decode, .frequency = 0, .number = ptype, }; /* Remember to keep this in sync with modules/services_discovery/sap.c */ switch (ptype) { case 0: msg_Dbg (demux, "detected G.711 mu-law"); pt.init = pcmu_init; pt.frequency = 8000; break; case 3: msg_Dbg (demux, "detected GSM"); pt.init = gsm_init; pt.frequency = 8000; break; case 8: msg_Dbg (demux, "detected G.711 A-law"); pt.init = pcma_init; pt.frequency = 8000; break; case 10: msg_Dbg (demux, "detected stereo PCM"); pt.init = l16s_init; pt.frequency = 44100; break; case 11: msg_Dbg (demux, "detected mono PCM"); pt.init = l16m_init; pt.frequency = 44100; break; case 12: msg_Dbg (demux, "detected QCELP"); pt.init = qcelp_init; pt.frequency = 8000; break; case 14: msg_Dbg (demux, "detected MPEG Audio"); pt.init = mpa_init; pt.decode = mpa_decode; pt.frequency = 90000; break; case 32: msg_Dbg (demux, "detected MPEG Video"); pt.init = mpv_init; pt.decode = mpv_decode; pt.frequency = 90000; break; case 33: msg_Dbg (demux, "detected MPEG2 TS"); pt.init = ts_init; pt.destroy = stream_destroy; pt.decode = stream_decode; pt.frequency = 90000; break; default: /* * If the rtp payload type is unknown then check demux if it is specified */ if (!strcmp(demux->psz_demux, "h264") || !strcmp(demux->psz_demux, "ts")) { msg_Dbg (demux, "dynamic payload format %s specified by demux", demux->psz_demux); pt.init = demux_init; pt.destroy = stream_destroy; pt.decode = stream_decode; pt.frequency = 90000; break; } if (ptype >= 96) { char *dynamic = var_InheritString(demux, "rtp-dynamic-pt"); if (dynamic == NULL) ; else if (!strcmp(dynamic, "theora")) { msg_Dbg (demux, "assuming Theora Encoded Video"); pt.init = theora_init; pt.destroy = xiph_destroy; pt.decode = xiph_decode; pt.frequency = 90000; } else msg_Err (demux, "unknown dynamic payload format `%s' " "specified", dynamic); free (dynamic); } msg_Err (demux, "unspecified payload format (type %"PRIu8")", ptype); msg_Info (demux, "A valid SDP is needed to parse this RTP stream."); vlc_dialog_display_error (demux, N_("SDP required"), N_("A description in SDP format is required to receive the RTP " "stream. Note that rtp:// URIs cannot work with dynamic " "RTP payload format (%"PRIu8")."), ptype); return; } rtp_add_type (demux, session, &pt); }
/* see http://www.iana.org/assignments/rtp-parameters */ int rtp_autodetect (demux_t *demux, rtp_session_t *session, const block_t *block) { uint8_t ptype = rtp_ptype (block); rtp_pt_t pt = { .init = NULL, .destroy = codec_destroy, .decode = codec_decode, .frequency = 0, .number = ptype, }; /* Remember to keep this in sync with modules/services_discovery/sap.c */ switch (ptype) { case 0: msg_Dbg (demux, "detected G.711 mu-law"); pt.init = pcmu_init; pt.frequency = 8000; break; case 3: msg_Dbg (demux, "detected GSM"); pt.init = gsm_init; pt.frequency = 8000; break; case 8: msg_Dbg (demux, "detected G.711 A-law"); pt.init = pcma_init; pt.frequency = 8000; break; case 10: msg_Dbg (demux, "detected stereo PCM"); pt.init = l16s_init; pt.frequency = 44100; break; case 11: msg_Dbg (demux, "detected mono PCM"); pt.init = l16m_init; pt.frequency = 44100; break; case 12: msg_Dbg (demux, "detected QCELP"); pt.init = qcelp_init; pt.frequency = 8000; break; case 14: msg_Dbg (demux, "detected MPEG Audio"); pt.init = mpa_init; pt.decode = mpa_decode; pt.frequency = 90000; break; case 32: msg_Dbg (demux, "detected MPEG Video"); pt.init = mpv_init; pt.decode = mpv_decode; pt.frequency = 90000; break; case 33: msg_Dbg (demux, "detected MPEG2 TS"); pt.init = ts_init; pt.destroy = stream_destroy; pt.decode = stream_decode; pt.frequency = 90000; break; default: return -1; } rtp_add_type (demux, session, &pt); return 0; }