Commit 832cb393 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

RTP sout: rework sample-based audio codecs to not exceed the MTU

Send as much data as the packetization AND the MTU allow
parent e72ecce9
......@@ -812,6 +812,22 @@ static void sprintf_hexa( char *s, uint8_t *p_data, int i_data )
s[2*i_data] = '\0';
}
/**
* Shrink the MTU down to a fixed packetization time (for audio).
*/
static void
rtp_set_ptime (sout_stream_id_t *id, unsigned ptime_ms, size_t bytes)
{
/* Samples per second */
size_t spl = (id->i_clock_rate - 1) * ptime_ms / 1000 + 1;
bytes *= id->i_channels;
spl *= bytes;
if (spl < rtp_mtu (id)) /* MTU is big enough for ptime */
id->i_mtu = 12 + spl;
else /* MTU is too small for ptime, align to a sample boundary */
id->i_mtu = (id->i_mtu / bytes) * bytes;
}
/** Add an ES as a new RTP stream */
static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
......@@ -968,13 +984,15 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
id->i_payload_type = 0;
id->psz_enc = "PCMU";
id->pf_packetize = rtp_packetize_l8;
id->pf_packetize = rtp_packetize_split;
rtp_set_ptime (id, 20, 1);
break;
case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
id->i_payload_type = 8;
id->psz_enc = "PCMA";
id->pf_packetize = rtp_packetize_l8;
id->pf_packetize = rtp_packetize_split;
rtp_set_ptime (id, 20, 1);
break;
case VLC_FOURCC( 's', '1', '6', 'b' ):
if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 )
......@@ -987,11 +1005,13 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
id->i_payload_type = 10;
}
id->psz_enc = "L16";
id->pf_packetize = rtp_packetize_l16;
id->pf_packetize = rtp_packetize_split;
rtp_set_ptime (id, 20, 1);
break;
case VLC_FOURCC( 'u', '8', ' ', ' ' ):
id->psz_enc = "L8";
id->pf_packetize = rtp_packetize_l8;
id->pf_packetize = rtp_packetize_split;
rtp_set_ptime (id, 20, 1);
break;
case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
case VLC_FOURCC( 'm', 'p', '3', ' ' ):
......@@ -1515,16 +1535,6 @@ size_t rtp_mtu (const sout_stream_id_t *id)
return id->i_mtu - 12;
}
/**
* @return number of audio samples to include for a given packetization time
* (this really only makes sense for audio formats).
*/
size_t rtp_plen (const sout_stream_id_t * id, unsigned ptime_ms)
{
return id->i_channels * (((id->i_clock_rate - 1) * ptime_ms / 1000) + 1);
}
/*****************************************************************************
* Non-RTP mux
*****************************************************************************/
......
......@@ -46,10 +46,7 @@ void rtp_packetize_common (sout_stream_id_t *id, block_t *out,
int b_marker, int64_t i_pts);
void rtp_packetize_send (sout_stream_id_t *id, block_t *out);
size_t rtp_mtu (const sout_stream_id_t *id);
size_t rtp_plen (const sout_stream_id_t * id, unsigned ptime);
int rtp_packetize_l16 (sout_stream_t *, sout_stream_id_t *, block_t *);
int rtp_packetize_l8 (sout_stream_t *, sout_stream_id_t *, block_t *);
int rtp_packetize_mpa (sout_stream_t *, sout_stream_id_t *, block_t *);
int rtp_packetize_mpv (sout_stream_t *, sout_stream_id_t *, block_t *);
int rtp_packetize_ac3 (sout_stream_t *, sout_stream_id_t *, block_t *);
......
......@@ -303,66 +303,6 @@ int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id,
return VLC_SUCCESS;
}
int rtp_packetize_l16( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in )
{
const uint8_t *p_data = in->p_buffer;
size_t i_data = in->i_buffer;
size_t i_plen = 2 * rtp_plen (id, 20);
for( unsigned i_packet = 0; i_data > 0; i_packet++ )
{
int i_payload = __MIN( i_plen, i_data );
block_t *out = block_New( p_stream, 12 + i_payload );
/* rtp common header */
rtp_packetize_common( id, out, 0,
(in->i_pts > 0 ? in->i_pts : in->i_dts) );
memcpy( &out->p_buffer[12], p_data, i_payload );
out->i_buffer = 12 + i_payload;
out->i_dts = in->i_dts + i_packet * 20000;
out->i_length = i_payload * 20000 / i_plen;
rtp_packetize_send( id, out );
p_data += i_payload;
i_data -= i_payload;
}
return VLC_SUCCESS;
}
int rtp_packetize_l8( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in )
{
const uint8_t *p_data = in->p_buffer;
size_t i_data = in->i_buffer;
size_t i_plen = rtp_plen (id, 20);
for( unsigned i_packet = 0; i_data > 0; i_packet++ )
{
int i_payload = __MIN( i_plen, i_data );
block_t *out = block_New( p_stream, 12 + i_payload );
/* rtp common header */
rtp_packetize_common( id, out, 0,
(in->i_pts > 0 ? in->i_pts : in->i_dts) );
memcpy( &out->p_buffer[12], p_data, i_payload );
out->i_buffer = 12 + i_payload;
out->i_dts = in->i_dts + i_packet * 20000;
out->i_length = i_payload * 20000 / i_plen;
rtp_packetize_send( id, out );
p_data += i_payload;
i_data -= i_payload;
}
return VLC_SUCCESS;
}
int rtp_packetize_mp4a( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in )
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment